From 7eacb0f86d2d1c50b05a4992134e0eb8d184a0f6 Mon Sep 17 00:00:00 2001 From: lijianguo Date: Wed, 26 Mar 2025 11:22:20 +0800 Subject: [PATCH 1/5] fix(timeouts): timeouts set error --- rootfs/api/models/config.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rootfs/api/models/config.py b/rootfs/api/models/config.py index 7be9ed19..07a4fb7b 100644 --- a/rootfs/api/models/config.py +++ b/rootfs/api/models/config.py @@ -265,3 +265,18 @@ def _update_limits(self, previous_config, replace_ptypes=[]): "the %s has already been used and cannot be deleted" % ptype) self._merge_data('limits', data, new_data) setattr(self, 'limits', data) + + def _update_termination_grace_period(self, previous_config, replace_ptypes=[]): + data = { + k: v for k, v in getattr(previous_config, 'termination_grace_period', {}).copy().items() + if k not in replace_ptypes + } + new_data = getattr(self, 'termination_grace_period', {}).copy() + # check procfile + for ptype, value in new_data.items(): + if value is None: + if ptype in self.app.ptypes: + raise UnprocessableEntity( + "the %s has already been used and cannot be deleted" % ptype) + self._merge_data('termination_grace_period', data, new_data) + setattr(self, 'termination_grace_period', data) From e24acc35cb2e7b3aacb8545b55691ab6e9228e9a Mon Sep 17 00:00:00 2001 From: lijianguo Date: Wed, 26 Mar 2025 11:45:24 +0800 Subject: [PATCH 2/5] fix(tls): tls force enable error --- rootfs/api/models/gateway.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootfs/api/models/gateway.py b/rootfs/api/models/gateway.py index af1cad24..9788e09c 100644 --- a/rootfs/api/models/gateway.py +++ b/rootfs/api/models/gateway.py @@ -222,7 +222,7 @@ def cleaned_rules(self): @property def tls_force_hostnames(self): tls = self.app.tls_set.latest() - q = Q(ptype__int=[s.ptype for s in self.services]) + q = Q(ptype__in=[s.ptype for s in self.services]) if not tls.certs_auto_enabled: q &= Q(certificate__isnull=False) domains = self.app.domain_set.filter(q) From 810073862b5f293982eae6c65f7e80f8d5dc2b0c Mon Sep 17 00:00:00 2001 From: lijianguo Date: Wed, 26 Mar 2025 16:46:07 +0800 Subject: [PATCH 3/5] chore(certs): allow re attach to update --- rootfs/api/models/certificate.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rootfs/api/models/certificate.py b/rootfs/api/models/certificate.py index d97d0c16..e2523857 100644 --- a/rootfs/api/models/certificate.py +++ b/rootfs/api/models/certificate.py @@ -192,9 +192,7 @@ def delete(self, *args, **kwargs): def attach(self, *args, **kwargs): # add the certificate to the domain domain = get_object_or_404(Domain, domain=kwargs['domain']) - if domain.certificate is not None: - raise AlreadyExists("Domain already has a certificate attached to it") - # create in kubernetes + ## create in kubernetes self.attach_in_kubernetes(domain) domain.certificate = self domain.save() From 94854bdaf28118786ca302ae3914a4e628a5051e Mon Sep 17 00:00:00 2001 From: lijianguo Date: Wed, 26 Mar 2025 16:47:27 +0800 Subject: [PATCH 4/5] chore(controller): https_enforced when has domains --- rootfs/api/models/gateway.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rootfs/api/models/gateway.py b/rootfs/api/models/gateway.py index 9788e09c..6aa15ccc 100644 --- a/rootfs/api/models/gateway.py +++ b/rootfs/api/models/gateway.py @@ -260,7 +260,8 @@ def refresh_to_k8s(self): if self.routable: parent_refs, http_parent_refs = self._get_all_parent_refs() tls = self.app.tls_set.latest() - if tls.https_enforced and self.kind == "HTTPRoute": + # requestRedirect only when has tls or certs + if tls.https_enforced and self.kind == "HTTPRoute" and self.tls_force_hostnames: self._https_enforced_to_k8s(http_parent_refs) elif self.kind == "HTTPRoute": parent_refs.extend(http_parent_refs) From f8835466315a49dcd65645e81f583e0c44e89c61 Mon Sep 17 00:00:00 2001 From: lijianguo Date: Wed, 26 Mar 2025 17:55:26 +0800 Subject: [PATCH 5/5] chore(controller): pod pending has not containerStatuses --- rootfs/api/models/certificate.py | 4 ++-- rootfs/api/models/config.py | 2 +- rootfs/api/tests/test_certificate_use_case_4.py | 8 ++++---- rootfs/scheduler/resources/pod.py | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rootfs/api/models/certificate.py b/rootfs/api/models/certificate.py index e2523857..b1f9cd5b 100644 --- a/rootfs/api/models/certificate.py +++ b/rootfs/api/models/certificate.py @@ -13,7 +13,7 @@ from django.contrib.auth import get_user_model from rest_framework.exceptions import ValidationError from api.utils import validate_label -from api.exceptions import AlreadyExists, ServiceUnavailable +from api.exceptions import ServiceUnavailable from scheduler import KubeException from .base import AuditedModel from .domain import Domain @@ -192,7 +192,7 @@ def delete(self, *args, **kwargs): def attach(self, *args, **kwargs): # add the certificate to the domain domain = get_object_or_404(Domain, domain=kwargs['domain']) - ## create in kubernetes + # create in kubernetes self.attach_in_kubernetes(domain) domain.certificate = self domain.save() diff --git a/rootfs/api/models/config.py b/rootfs/api/models/config.py index 07a4fb7b..4c7742f3 100644 --- a/rootfs/api/models/config.py +++ b/rootfs/api/models/config.py @@ -268,7 +268,7 @@ def _update_limits(self, previous_config, replace_ptypes=[]): def _update_termination_grace_period(self, previous_config, replace_ptypes=[]): data = { - k: v for k, v in getattr(previous_config, 'termination_grace_period', {}).copy().items() + k: v for k, v in getattr(previous_config, 'termination_grace_period', {}).copy().items() # noqa if k not in replace_ptypes } new_data = getattr(self, 'termination_grace_period', {}).copy() diff --git a/rootfs/api/tests/test_certificate_use_case_4.py b/rootfs/api/tests/test_certificate_use_case_4.py index 9bfd62c6..f12b7634 100644 --- a/rootfs/api/tests/test_certificate_use_case_4.py +++ b/rootfs/api/tests/test_certificate_use_case_4.py @@ -168,8 +168,8 @@ def test_certificate_attach_overwrite(self): '{}/{}/domain/'.format(self.url, 'bar-com'), {'domain': 'foo.com'} ) - # Should be a 409 Conflict since it already existed - self.assertEqual(response.status_code, 409) + # allow re attach to update + self.assertEqual(response.status_code, 201) # Assert that domain and cert are still the original response = self.client.get( @@ -180,7 +180,7 @@ def test_certificate_attach_overwrite(self): expected = { 'name': 'foo-com', 'common_name': 'foo.com', - 'domains': ['foo.com'] + 'domains': [] } for key, value in list(expected.items()): self.assertEqual( @@ -197,7 +197,7 @@ def test_certificate_attach_overwrite(self): expected = { 'name': 'bar-com', 'common_name': 'bar.com', - 'domains': [] + 'domains': ['foo.com'] } for key, value in list(expected.items()): self.assertEqual( diff --git a/rootfs/scheduler/resources/pod.py b/rootfs/scheduler/resources/pod.py index a9f733ab..13af0524 100644 --- a/rootfs/scheduler/resources/pod.py +++ b/rootfs/scheduler/resources/pod.py @@ -413,7 +413,7 @@ def readiness_status(self, pod): """Check if the pod container have passed the readiness probes""" name = '{}-{}'.format(pod['metadata']['labels']['app'], pod['metadata']['labels']['type']) # find the right container in case there are many on the pod - container = self.find_container(name, pod['status']['containerStatuses']) + container = self.find_container(name, pod['status'].get('containerStatuses', [])) if container is None: # Seems like the most sensible default return 'Unknown' @@ -466,7 +466,7 @@ def pending_status(self, pod): name = '{}-{}'.format(pod['metadata']['labels']['app'], pod['metadata']['labels']['type']) # find the right container in case there are many on the pod - container = self.pod.find_container(name, pod['status']['containerStatuses']) + container = self.find_container(name, pod['status'].get('containerStatuses', [])) if container is None: # Return Pending if nothing else can be found return 'Pending', '' @@ -596,7 +596,7 @@ def _handle_pending_pods(self, namespace, labels): phase = pod['status']['phase'] name = '{}-{}'.format(pod['metadata']['labels']['app'], pod['metadata']['labels']['type']) - container = self.find_container(name, pod['status']['containerStatuses']) + container = self.find_container(name, pod['status'].get('containerStatuses', [])) # phase is Running, but state is waiting in CrashLoopBackOff if phase not in ['Pending', 'ContainerCreating'] and \ (phase == 'Running' and 'waiting' not in container['state'].keys()): @@ -748,7 +748,7 @@ def _handle_not_ready_pods(self, namespace, labels): name = '{}-{}'.format(pod['metadata']['labels']['app'], pod['metadata']['labels']['type']) # noqa # find the right container in case there are many on the pod - container = self.find_container(name, pod['status']['containerStatuses']) + container = self.find_container(name, pod['status'].get('containerStatuses', [])) if container is None or container['ready'] == 'true': continue