|
15 | 15 | DEFAULT_HTTP_PORT = 80 |
16 | 16 | DEFAULT_HTTPS_PORT = 443 |
17 | 17 |
|
| 18 | +HOSTNAME_PROTOCOLS = ("TLS", "HTTP", "HTTPS") |
| 19 | + |
18 | 20 |
|
19 | 21 | class Gateway(AuditedModel): |
20 | 22 | app = models.ForeignKey('App', on_delete=models.CASCADE) |
@@ -46,27 +48,27 @@ def listeners(self): |
46 | 48 | domains = list(self._get_tls_domain(auto_tls)) |
47 | 49 | for item in self.ports: |
48 | 50 | port, protocol = item["port"], item["protocol"] |
49 | | - if item["protocol"] in ("TLS", "HTTPS"): |
| 51 | + if item["protocol"] in HOSTNAME_PROTOCOLS: |
50 | 52 | for domain in domains: |
51 | | - secret_name = f"{self.app.id}-auto-tls" if auto_tls else ( |
52 | | - domain.certificate.name if domain.certificate else None) |
53 | | - if secret_name is None: |
54 | | - continue |
55 | | - listeners.append({ |
| 53 | + listener = { |
56 | 54 | "allowedRoutes": {"namespaces": {"from": "All"}}, |
57 | 55 | "name": self._get_listener_name(port, protocol, domains.index(domain)), |
58 | 56 | "port": port, |
59 | 57 | "hostname": domain.domain, |
60 | 58 | "protocol": protocol, |
61 | | - "tls": {"certificateRefs": [{"kind": "Secret", "name": secret_name}]}, |
62 | | - }) |
63 | | - else: |
64 | | - listeners.append({ |
65 | | - "allowedRoutes": {"namespaces": {"from": "All"}}, |
66 | | - "name": self._get_listener_name(port, protocol, 0), |
67 | | - "port": port, |
68 | | - "protocol": protocol, |
69 | | - }) |
| 59 | + } |
| 60 | + secret_name = f"{self.app.id}-auto-tls" if auto_tls else ( |
| 61 | + domain.certificate.name if domain.certificate else None) |
| 62 | + if secret_name: |
| 63 | + listener["tls"] = { |
| 64 | + "certificateRefs": [{"kind": "Secret", "name": secret_name}]} |
| 65 | + listeners.append(listener) |
| 66 | + listeners.append({ |
| 67 | + "allowedRoutes": {"namespaces": {"from": "All"}}, |
| 68 | + "name": self._get_listener_name(port, protocol, 0), |
| 69 | + "port": port, |
| 70 | + "protocol": protocol, |
| 71 | + }) |
70 | 72 | return listeners |
71 | 73 |
|
72 | 74 | @property |
@@ -183,6 +185,11 @@ def protocols(self): |
183 | 185 | raise NotImplementedError("this kind is not supported") |
184 | 186 | return self.PROTOCOLS_CHOICES[self.kind] |
185 | 187 |
|
| 188 | + @property |
| 189 | + def hostnames(self): |
| 190 | + return [domain.domain for domain in self.app.domain_set.filter( |
| 191 | + procfile_type=self.procfile_type)] |
| 192 | + |
186 | 193 | @property |
187 | 194 | def default_rules(self): |
188 | 195 | service = get_object_or_404(self.app.service_set, procfile_type=self.procfile_type) |
@@ -259,7 +266,7 @@ def change_default_tls(self): |
259 | 266 | def attach(self, gateway_name, port): |
260 | 267 | ok, msg = self._check_parent(gateway_name, port) |
261 | 268 | if not ok: |
262 | | - return ok, msg |
| 269 | + return ok, {"detail": msg} |
263 | 270 | parent_ref = {"name": gateway_name, "port": port} |
264 | 271 | if parent_ref in self.parent_refs: |
265 | 272 | return False, {"detail": "gateway and port already exist in this route"} |
@@ -302,38 +309,38 @@ def _check_parent(self, gateway_name, port): |
302 | 309 | try: |
303 | 310 | gateway = self.app.gateway_set.filter(name=gateway_name).latest() |
304 | 311 | except Gateway.DoesNotExist: |
305 | | - return False, {"detail": f"this gateway {gateway_name} does not exist"} |
| 312 | + return False, f"this gateway {gateway_name} does not exist" |
306 | 313 | is_listener_allowed = False |
307 | 314 | for gateway_port in gateway.ports: |
308 | 315 | if port == gateway_port.get("port") and \ |
309 | 316 | self.kind.split("Route")[0] in gateway_port.get("protocol"): |
310 | 317 | is_listener_allowed = True |
311 | 318 | if not is_listener_allowed: |
312 | | - return False, {"detail": f"this gateway does not allow {self.kind} port {port} bind, \nplease add gateway listener first."} # noqa |
| 319 | + return False, "listener does not exist, please add gateway listener first." |
313 | 320 | for route in self.app.route_set.exclude(app=self.app, name=self.name): |
314 | 321 | for parent_ref in route.parent_refs: |
315 | 322 | if parent_ref["name"] == gateway_name and parent_ref["port"] == port: |
316 | | - for protocol in self.protocols: |
317 | | - if protocol in route.protocols: |
318 | | - return False, {"detail": "this listener has already been referenced"} |
| 323 | + if not set(route.protocols).issubset(HOSTNAME_PROTOCOLS) and ( |
| 324 | + set(route.protocols).issubset(self.protocols) or |
| 325 | + set(self.protocols).issubset(route.protocols)): |
| 326 | + return False, "this listener has already been referenced" |
319 | 327 | return True, "" |
320 | 328 |
|
321 | 329 | def _refresh_to_k8s(self, rules, parent_refs): |
322 | 330 | try: |
323 | 331 | k8s_route = getattr(self.scheduler(), self.kind.lower()) |
324 | | - hostnames = [domain.domain for domain in self.app.domain_set.all()] |
325 | 332 | try: |
326 | 333 | data = k8s_route.get(self.app.id, self.name).json() |
327 | 334 | k8s_route.patch(self.app.id, self.name, **{ |
328 | 335 | "rules": rules, |
329 | | - "hostnames": hostnames, |
| 336 | + "hostnames": self.hostnames, |
330 | 337 | "parent_refs": parent_refs, |
331 | 338 | "version": data["metadata"]["resourceVersion"], |
332 | 339 | }) |
333 | 340 | except KubeException: |
334 | 341 | k8s_route.create(self.app.id, self.name, **{ |
335 | 342 | "rules": rules, |
336 | | - "hostnames": hostnames, |
| 343 | + "hostnames": self.hostnames, |
337 | 344 | "parent_refs": parent_refs, |
338 | 345 | }) |
339 | 346 | except KubeException as e: |
|
0 commit comments