Skip to content

Commit f132b25

Browse files
author
Matthew Fisher
authored
fix(api): validate app name against k8s service regex (#1163)
* fix(api): app name must start with an alphabetic character * fix(api): app name cannot end with a hyphen
1 parent 890a263 commit f132b25

5 files changed

Lines changed: 26 additions & 8 deletions

File tree

rootfs/api/migrations/0001_initial.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
2020
('uuid', api.fields.UuidField(auto_created=True, primary_key=True, serialize=False, editable=False, max_length=32, unique=True, verbose_name='UUID')),
2121
('created', models.DateTimeField(auto_now_add=True)),
2222
('updated', models.DateTimeField(auto_now=True)),
23-
('id', models.SlugField(max_length=24, unique=True, null=True, validators=[api.models.validate_id_is_docker_compatible, api.models.validate_reserved_names])),
23+
('id', models.SlugField(max_length=24, unique=True, null=True, validators=[api.models.validate_app_id, api.models.validate_reserved_names])),
2424
('structure', jsonfield.fields.JSONField(default={}, blank=True, validators=[api.models.validate_app_structure])),
2525
('owner', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
2626
],

rootfs/api/migrations/0002_auto_20151215_0352.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Migration(migrations.Migration):
1414
migrations.AlterField(
1515
model_name='app',
1616
name='id',
17-
field=models.SlugField(max_length=24, unique=True, null=True, validators=[api.models.validate_id_is_docker_compatible, api.models.validate_reserved_names]),
17+
field=models.SlugField(max_length=24, unique=True, null=True, validators=[api.models.validate_app_id, api.models.validate_reserved_names]),
1818
),
1919
migrations.AlterField(
2020
model_name='app',

rootfs/api/models/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class Meta:
113113
abstract = True
114114

115115

116-
from .app import App, validate_id_is_docker_compatible, validate_reserved_names, validate_app_structure # noqa
116+
from .app import App, validate_app_id, validate_reserved_names, validate_app_structure # noqa
117117
from .appsettings import AppSettings # noqa
118118
from .build import Build # noqa
119119
from .certificate import Certificate, validate_certificate # noqa

rootfs/api/models/app.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ def get_session():
5252

5353

5454
# http://kubernetes.io/v1.1/docs/design/identifiers.html
55-
def validate_id_is_docker_compatible(value):
55+
def validate_app_id(value):
5656
"""
5757
Check that the value follows the kubernetes name constraints
5858
"""
59-
match = re.match(r'^[a-z0-9-]+$', value)
59+
match = re.match(r'[a-z]([a-z0-9-]*[a-z0-9])?$', value)
6060
if not match:
61-
raise ValidationError("App name can only contain a-z (lowercase), 0-9 and hyphens")
61+
raise ValidationError("App name must start with an alphabetic character, cannot end with a"
62+
+ " hyphen and can only contain a-z (lowercase), 0-9 and hyphens.")
6263

6364

6465
def validate_app_structure(value):
@@ -87,7 +88,7 @@ class App(UuidAuditedModel):
8788

8889
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
8990
id = models.SlugField(max_length=24, unique=True, null=True,
90-
validators=[validate_id_is_docker_compatible,
91+
validators=[validate_app_id,
9192
validate_reserved_names])
9293
structure = JSONField(default={}, blank=True, validators=[validate_app_structure])
9394

rootfs/api/tests/test_app.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,24 @@ def test_app_errors(self, mock_requests):
151151
response = self.client.post('/v2/apps', {'id': 'camelCase'})
152152
self.assertContains(
153153
response,
154-
'App name can only contain a-z (lowercase), 0-9 and hyphens',
154+
'App name must start with an alphabetic character, cannot end with a hyphen and can '
155+
+ 'only contain a-z (lowercase), 0-9 and hyphens.',
156+
status_code=400
157+
)
158+
159+
response = self.client.post('/v2/apps', {'id': '123name-starts-with-numbers'})
160+
self.assertContains(
161+
response,
162+
'App name must start with an alphabetic character, cannot end with a hyphen and can '
163+
+ 'only contain a-z (lowercase), 0-9 and hyphens.',
164+
status_code=400
165+
)
166+
167+
response = self.client.post('/v2/apps', {'id': 'name-ends-with-hyphen-'})
168+
self.assertContains(
169+
response,
170+
'App name must start with an alphabetic character, cannot end with a hyphen and can '
171+
+ 'only contain a-z (lowercase), 0-9 and hyphens.',
155172
status_code=400
156173
)
157174

0 commit comments

Comments
 (0)