diff --git a/rootfs/api/models/certificate.py b/rootfs/api/models/certificate.py index d97d0c16..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,8 +192,6 @@ 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 self.attach_in_kubernetes(domain) domain.certificate = self diff --git a/rootfs/api/models/config.py b/rootfs/api/models/config.py index 7be9ed19..4c7742f3 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() # noqa + 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) diff --git a/rootfs/api/models/gateway.py b/rootfs/api/models/gateway.py index af1cad24..6aa15ccc 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) @@ -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) 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