Skip to content
This repository was archived by the owner on May 6, 2020. It is now read-only.

Commit 53871f9

Browse files
authored
Merge pull request #1045 from kmala/bug
fix(whitelist): Handle empty whitelist from user gracefully
2 parents 2f5c019 + d66c20c commit 53871f9

File tree

4 files changed

+60
-16
lines changed

4 files changed

+60
-16
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.10 on 2016-09-08 17:48
3+
from __future__ import unicode_literals
4+
5+
import django.contrib.postgres.fields
6+
from django.db import migrations, models
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('api', '0017_appsettings_autoscale'),
13+
]
14+
15+
operations = [
16+
migrations.AlterField(
17+
model_name='appsettings',
18+
name='whitelist',
19+
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=50), default=None, size=None),
20+
),
21+
]

rootfs/api/models/app.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,8 +970,13 @@ def whitelist(self, whitelist):
970970
service = self._fetch_service_config(self.id)
971971

972972
try:
973-
addresses = ",".join(address for address in whitelist)
974-
service['metadata']['annotations']['router.deis.io/whitelist'] = addresses
973+
if whitelist:
974+
addresses = ",".join(address for address in whitelist)
975+
service['metadata']['annotations']['router.deis.io/whitelist'] = addresses
976+
elif 'router.deis.io/whitelist' in service['metadata']['annotations']:
977+
service['metadata']['annotations'].pop('router.deis.io/whitelist', None)
978+
else:
979+
return
975980
self._scheduler.svc.update(self.id, self.id, data=service)
976981
except KubeException as e:
977982
raise ServiceUnavailable(str(e)) from e

rootfs/api/models/appsettings.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ class AppSettings(UuidAuditedModel):
1919
app = models.ForeignKey('App', on_delete=models.CASCADE)
2020
maintenance = models.NullBooleanField(default=None)
2121
routable = models.NullBooleanField(default=None)
22-
whitelist = ArrayField(models.CharField(max_length=50), default=[])
22+
# the default values is None to differentiate from user sending an empty whitelist
23+
# and user just updating other fields meaning the values needs to be copied from prev release
24+
whitelist = ArrayField(models.CharField(max_length=50), default=None)
2325
autoscale = JSONField(default={}, blank=True)
2426

2527
class Meta:
@@ -70,13 +72,14 @@ def update_routable(self, previous_settings):
7072
self.summary += ["{} changed routablity from {} to {}".format(self.owner, old, new)]
7173

7274
def update_whitelist(self, previous_settings):
73-
# If no previous settings then assume it is the first record and do nothing
75+
# If no previous settings then assume it is the first record and set as empty
76+
# to prevent from database constraint violation
7477
if not previous_settings:
75-
return
78+
setattr(self, 'whitelist', [])
7679
old = getattr(previous_settings, 'whitelist', [])
77-
new = getattr(self, 'whitelist', [])
80+
new = getattr(self, 'whitelist', None)
7881
# if nothing changed copy the settings from previous
79-
if len(new) == 0 and len(old) != 0:
82+
if new is None and old is not None:
8083
setattr(self, 'whitelist', old)
8184
elif set(old) != set(new):
8285
self.app.whitelist(new)

rootfs/api/tests/test_app_settings.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_settings_whitelist(self, mock_requests):
9999
app_id = self.create_app()
100100
app = App.objects.get(id=app_id)
101101
# add addresses to empty whitelist
102-
addresses = ["1.2.3.4", "0.0.0.0/0"]
102+
addresses = ["0.0.0.0/0"]
103103
whitelist = {'addresses': addresses}
104104
response = self.client.post(
105105
'/v2/apps/{app_id}/whitelist'.format(**locals()),
@@ -108,12 +108,34 @@ def test_settings_whitelist(self, mock_requests):
108108
self.assertEqual(set(response.data['addresses']),
109109
set(app.appsettings_set.latest().whitelist), response.data)
110110
self.assertEqual(set(response.data['addresses']), set(addresses), response.data)
111+
111112
# get the whitelist
112113
response = self.client.get('/v2/apps/{app_id}/whitelist'.format(**locals()))
113114
self.assertEqual(response.status_code, 200, response.data)
114115
self.assertEqual(set(response.data['addresses']),
115116
set(app.appsettings_set.latest().whitelist), response.data)
116117
self.assertEqual(set(response.data['addresses']), set(addresses), response.data)
118+
119+
# delete an address from whitelist
120+
whitelist = {'addresses': ["0.0.0.0/0"]}
121+
addresses.remove("0.0.0.0/0")
122+
response = self.client.delete(
123+
'/v2/apps/{app_id}/whitelist'.format(**locals()),
124+
whitelist)
125+
self.assertEqual(response.status_code, 204, response.data)
126+
self.assertEqual(set(addresses), set(app.appsettings_set.latest().whitelist))
127+
128+
# add addresses to empty whitelist
129+
addresses = ["0.0.0.0/0"]
130+
whitelist = {'addresses': addresses}
131+
response = self.client.post(
132+
'/v2/apps/{app_id}/whitelist'.format(**locals()),
133+
whitelist)
134+
self.assertEqual(response.status_code, 201, response.data)
135+
self.assertEqual(set(response.data['addresses']),
136+
set(app.appsettings_set.latest().whitelist), response.data)
137+
self.assertEqual(set(response.data['addresses']), set(addresses), response.data)
138+
117139
# add addresses to non-empty whitelist
118140
whitelist = {'addresses': ["2.3.4.5"]}
119141
addresses.extend(["2.3.4.5"])
@@ -124,6 +146,7 @@ def test_settings_whitelist(self, mock_requests):
124146
self.assertEqual(set(response.data['addresses']),
125147
set(app.appsettings_set.latest().whitelist), response.data)
126148
self.assertEqual(set(response.data['addresses']), set(addresses), response.data)
149+
127150
# add exisitng addresses to whitelist
128151
response = self.client.post(
129152
'/v2/apps/{app_id}/whitelist'.format(**locals()),
@@ -135,14 +158,6 @@ def test_settings_whitelist(self, mock_requests):
135158
'/v2/apps/{app_id}/whitelist'.format(**locals()),
136159
whitelist)
137160
self.assertEqual(response.status_code, 422)
138-
# delete an address from whitelist
139-
whitelist = {'addresses': ["2.3.4.5"]}
140-
addresses.remove("2.3.4.5")
141-
response = self.client.delete(
142-
'/v2/apps/{app_id}/whitelist'.format(**locals()),
143-
whitelist)
144-
self.assertEqual(response.status_code, 204, response.data)
145-
self.assertEqual(set(addresses), set(app.appsettings_set.latest().whitelist))
146161
# pass invalid address
147162
whitelist = {'addresses': ["2.3.4.6.7"]}
148163
response = self.client.post(

0 commit comments

Comments
 (0)