Skip to content

Commit a4d58d8

Browse files
committed
fix(validation): success threshold can only be equal to one when setting liveness probe. Error properly
Kubernetes has this restriction, catch it before it ever makes it that far. Introducing jmespath now to later use in other places as well Fixes #873
1 parent b3c2024 commit a4d58d8

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

rootfs/api/serializers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
import json
6+
import jmespath
67
import re
78
import jsonschema
89
import idna
@@ -337,6 +338,15 @@ def validate_healthcheck(self, data):
337338
raise serializers.ValidationError(
338339
"could not validate {}: {}".format(value, e.message))
339340

341+
# http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_probe
342+
# liveness only supports successThreshold=1, no other value
343+
# This is not in the schema since readiness supports other values
344+
threshold = jmespath.search('livenessProbe.successThreshold', data)
345+
if threshold is not None and threshold != 1:
346+
raise serializers.ValidationError(
347+
'livenessProbe successThreshold can only be 1'
348+
)
349+
340350
return data
341351

342352

rootfs/api/tests/test_config.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,9 @@ def test_config_healthchecks(self, mock_requests):
833833
self.assertIn('readinessProbe', resp.data['healthcheck'])
834834
self.assertEqual(resp.data['healthcheck'], readiness_probe['healthcheck'])
835835

836-
liveness_probe = {'healthcheck': {'livenessProbe': {'httpGet': {'port': 5000}}}}
836+
liveness_probe = {'healthcheck': {'livenessProbe':
837+
{'httpGet': {'port': 5000},
838+
'successThreshold': 1}}}
837839
resp = self.client.post(
838840
'/v2/apps/{app_id}/config'.format(**locals()),
839841
liveness_probe)
@@ -879,6 +881,16 @@ def test_config_healthchecks_validations(self, mock_requests):
879881
)
880882
self.assertEqual(resp.status_code, 400, response.data)
881883

884+
# set liveness success threshold to a non-1 value
885+
# Don't set one of the mandatory value
886+
resp = self.client.post(
887+
'/v2/apps/{app_id}/config'.format(**locals()),
888+
{'healthcheck': {'livenessProbe':
889+
{'httpGet': {'path': '/', 'port': 5000},
890+
'successThreshold': 5}}}
891+
)
892+
self.assertEqual(resp.status_code, 400, response.data)
893+
882894
def test_config_healthchecks_legacy(self, mock_requests):
883895
"""
884896
Test that when a user uses `deis config:set HEALTHCHECK_URL=/`, the config

rootfs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ django-guardian==1.4.4
66
djangorestframework==3.4.0
77
docker-py==1.9.0
88
gunicorn==19.6.0
9+
jmespath==0.9.0
910
jsonfield==1.0.3
1011
morph==0.1.2
1112
ndg-httpsclient==0.4.2

0 commit comments

Comments
 (0)