|
1 | 1 | import logging |
2 | | - |
| 2 | +import jsonschema |
| 3 | +from functools import partial |
3 | 4 | from django.db import models |
4 | 5 | from django.conf import settings |
5 | 6 | from django.contrib.auth import get_user_model |
| 7 | +from rest_framework.exceptions import ValidationError |
6 | 8 | from api.exceptions import ServiceUnavailable |
7 | 9 | from scheduler import KubeException |
8 | 10 | from .base import AuditedModel |
9 | 11 |
|
| 12 | + |
10 | 13 | User = get_user_model() |
11 | 14 | logger = logging.getLogger(__name__) |
| 15 | +service_ports_schema = { |
| 16 | + "$schema": "http://json-schema.org/schema#", |
| 17 | + "type": "array", |
| 18 | + "minItems": 1, |
| 19 | + "items": { |
| 20 | + "type": "object", |
| 21 | + "properties": { |
| 22 | + "name": {"type": "string"}, |
| 23 | + "port": {"type": "integer"}, |
| 24 | + "protocol": {"type": "string"}, |
| 25 | + "targetPort": {"type": "integer"}, |
| 26 | + }, |
| 27 | + "required": ["name", "port", "protocol", "targetPort"], |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | + |
| 32 | +def validate_json(value, schema): |
| 33 | + if value is not None: |
| 34 | + try: |
| 35 | + jsonschema.validate(value, schema) |
| 36 | + except jsonschema.ValidationError as e: |
| 37 | + raise ValidationError(e.message) |
| 38 | + return value |
12 | 39 |
|
13 | 40 |
|
14 | 41 | class Service(AuditedModel): |
15 | 42 | owner = models.ForeignKey(User, on_delete=models.PROTECT) |
16 | 43 | app = models.ForeignKey('App', on_delete=models.CASCADE) |
17 | | - ports = models.JSONField(default=list) |
| 44 | + ports = models.JSONField( |
| 45 | + default=list, validators=[partial(validate_json, schema=service_ports_schema)]) |
18 | 46 | canary = models.BooleanField(default=False) |
19 | 47 | procfile_type = models.TextField() |
20 | 48 |
|
@@ -58,11 +86,11 @@ def add_port(self, port, protocol, target_port): |
58 | 86 | }) |
59 | 87 |
|
60 | 88 | def update_port(self, port, protocol, target_port): |
61 | | - port = self.get_port(port, "TCP") |
62 | | - if not port or port["targetPort"] != target_port: |
63 | | - if port and port["targetPort"] != target_port: |
64 | | - self.remove_port(port, "TCP") |
65 | | - self.add_port(port, "TCP", target_port) |
| 89 | + item = self.get_port(port, protocol) |
| 90 | + if not item or item["targetPort"] != target_port: |
| 91 | + if item and item["targetPort"] != target_port: |
| 92 | + self.remove_port(port, protocol) |
| 93 | + self.add_port(port, protocol, target_port) |
66 | 94 | return True |
67 | 95 | return False |
68 | 96 |
|
|
0 commit comments