Skip to content

Commit a5b56f5

Browse files
committed
refactor upstream validator
1 parent 53f5af4 commit a5b56f5

File tree

4 files changed

+59
-116
lines changed

4 files changed

+59
-116
lines changed

microservices/gatewayApi/tests/routes/v1/test_v1_validate_upstream.py renamed to microservices/gatewayApi/tests/utils/test_validate_upstream.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import yaml
88
import pytest
9-
from v1.routes.gateway import validate_upstream
9+
from utils.validators import validate_upstream
1010

1111
def test_upstream_good(app):
1212
payload = '''

microservices/gatewayApi/utils/validators.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
import re
3+
from urllib.parse import urlparse
34

45
namespace_validation_rule='^[a-z][a-z0-9-]{4,14}$'
56

@@ -16,3 +17,58 @@ def host_valid(input_string):
1617
# match = regex.match(str(input_string))
1718
# return bool(match is not None)
1819

20+
def validate_upstream(yaml, ns_attributes, protected_kube_namespaces, do_validate_upstreams: bool = False):
21+
errors = []
22+
23+
perm_upstreams = ns_attributes.get('perm-upstreams', [])
24+
25+
allow_protected_ns = ns_attributes.get('perm-protected-ns', ['deny'])[0] == 'allow'
26+
27+
# A service host must not contain a list of protected
28+
if 'services' in yaml:
29+
for service in yaml['services']:
30+
if 'url' in service:
31+
try:
32+
u = urlparse(service["url"])
33+
if u.hostname is None:
34+
errors.append("service upstream has invalid url specified (e1)")
35+
else:
36+
validate_upstream_host(u.hostname, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams)
37+
except Exception as e:
38+
errors.append("service upstream has invalid url specified (e2)")
39+
40+
if 'host' in service:
41+
host = service["host"]
42+
validate_upstream_host(host, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams)
43+
44+
if len(errors) != 0:
45+
raise Exception('\n'.join(errors))
46+
47+
48+
def validate_upstream_host(_host, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams):
49+
host = _host.lower()
50+
51+
restricted = ['localhost', '127.0.0.1', '0.0.0.0']
52+
53+
if host in restricted:
54+
errors.append("service upstream is invalid (e1)")
55+
elif host.endswith('svc'):
56+
partials = host.split('.')
57+
# get the namespace, and make sure it is not in the protected_kube_namespaces list
58+
if len(partials) != 3:
59+
errors.append("service upstream is invalid (e2)")
60+
elif partials[1] in protected_kube_namespaces and allow_protected_ns is False:
61+
errors.append("service upstream is invalid (e3)")
62+
elif do_validate_upstreams and (partials[1] in perm_upstreams) is False:
63+
errors.append("service upstream is invalid (e6)")
64+
elif host.endswith('svc.cluster.local'):
65+
partials = host.split('.')
66+
# get the namespace, and make sure it is not in the protected_kube_namespaces list
67+
if len(partials) != 5:
68+
errors.append("service upstream is invalid (e4)")
69+
elif partials[1] in protected_kube_namespaces and allow_protected_ns is False:
70+
errors.append("service upstream is invalid (e5)")
71+
elif do_validate_upstreams and (partials[1] in perm_upstreams) is False:
72+
errors.append("service upstream is invalid (e6)")
73+
elif do_validate_upstreams:
74+
errors.append("service upstream is invalid (e6)")

microservices/gatewayApi/v1/routes/gateway.py

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from clients.ocp_routes import get_host_list, get_route_overrides
2525
from clients.ocp_gateway_secret import prep_submitted_config, prep_and_apply_secret, write_submitted_config
2626

27-
from utils.validators import host_valid
27+
from utils.validators import host_valid, validate_upstream
2828
from utils.transforms import plugins_transformations
2929
from utils.masking import mask
3030

@@ -484,63 +484,6 @@ def transform_host(host):
484484
else:
485485
return host
486486

487-
488-
def validate_upstream(yaml, ns_attributes, protected_kube_namespaces, do_validate_upstreams: bool = False):
489-
errors = []
490-
491-
perm_upstreams = ns_attributes.get('perm-upstreams', [])
492-
493-
allow_protected_ns = ns_attributes.get('perm-protected-ns', ['deny'])[0] == 'allow'
494-
495-
# A host must not contain a list of protected
496-
if 'services' in yaml:
497-
for service in yaml['services']:
498-
if 'url' in service:
499-
try:
500-
u = urlparse(service["url"])
501-
if u.hostname is None:
502-
errors.append("service upstream has invalid url specified (e1)")
503-
else:
504-
validate_upstream_host(u.hostname, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams)
505-
except Exception as e:
506-
errors.append("service upstream has invalid url specified (e2)")
507-
508-
if 'host' in service:
509-
host = service["host"]
510-
validate_upstream_host(host, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams)
511-
512-
if len(errors) != 0:
513-
raise Exception('\n'.join(errors))
514-
515-
516-
def validate_upstream_host(_host, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams):
517-
host = _host.lower()
518-
519-
restricted = ['localhost', '127.0.0.1', '0.0.0.0']
520-
521-
if host in restricted:
522-
errors.append("service upstream is invalid (e1)")
523-
elif host.endswith('svc'):
524-
partials = host.split('.')
525-
# get the namespace, and make sure it is not in the protected_kube_namespaces list
526-
if len(partials) != 3:
527-
errors.append("service upstream is invalid (e2)")
528-
elif partials[1] in protected_kube_namespaces and allow_protected_ns is False:
529-
errors.append("service upstream is invalid (e3)")
530-
elif do_validate_upstreams and (partials[1] in perm_upstreams) is False:
531-
errors.append("service upstream is invalid (e6)")
532-
elif host.endswith('svc.cluster.local'):
533-
partials = host.split('.')
534-
# get the namespace, and make sure it is not in the protected_kube_namespaces list
535-
if len(partials) != 5:
536-
errors.append("service upstream is invalid (e4)")
537-
elif partials[1] in protected_kube_namespaces and allow_protected_ns is False:
538-
errors.append("service upstream is invalid (e5)")
539-
elif do_validate_upstreams and (partials[1] in perm_upstreams) is False:
540-
errors.append("service upstream is invalid (e6)")
541-
elif do_validate_upstreams:
542-
errors.append("service upstream is invalid (e6)")
543-
544487
# Handle the two cases:
545488
# - pass in an empty config expecting all routes to be deleted ('upstreams' not in yaml)
546489
# - pass in a config with services ('services' in yaml)

microservices/gatewayApi/v2/routes/gateway.py

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from clients.portal import record_gateway_event
2020
from clients.kong import get_routes, register_kong_certs
2121
from clients.ocp_gateway_secret import prep_submitted_config
22-
from utils.validators import host_valid
22+
from utils.validators import host_valid, validate_upstream
2323
from utils.transforms import plugins_transformations
2424
from utils.masking import mask
2525

@@ -509,62 +509,6 @@ def transform_host(host):
509509
else:
510510
return host
511511

512-
def validate_upstream(yaml, ns_attributes, protected_kube_namespaces, do_validate_upstreams: bool = False):
513-
errors = []
514-
515-
perm_upstreams = ns_attributes.get('perm-upstreams', [])
516-
517-
allow_protected_ns = ns_attributes.get('perm-protected-ns', ['deny'])[0] == 'allow'
518-
519-
# A host must not contain a list of protected
520-
if 'services' in yaml:
521-
for service in yaml['services']:
522-
if 'url' in service:
523-
try:
524-
u = urlparse(service["url"])
525-
if u.hostname is None:
526-
errors.append("service upstream has invalid url specified (e1)")
527-
else:
528-
validate_upstream_host(u.hostname, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams)
529-
except Exception as e:
530-
errors.append("service upstream has invalid url specified (e2)")
531-
532-
if 'host' in service:
533-
host = service["host"]
534-
validate_upstream_host(host, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams)
535-
536-
if len(errors) != 0:
537-
raise Exception('\n'.join(errors))
538-
539-
540-
def validate_upstream_host(_host, errors, allow_protected_ns, protected_kube_namespaces, do_validate_upstreams, perm_upstreams):
541-
host = _host.lower()
542-
543-
restricted = ['localhost', '127.0.0.1', '0.0.0.0']
544-
545-
if host in restricted:
546-
errors.append("service upstream is invalid (e1)")
547-
elif host.endswith('svc'):
548-
partials = host.split('.')
549-
# get the namespace, and make sure it is not in the protected_kube_namespaces list
550-
if len(partials) != 3:
551-
errors.append("service upstream is invalid (e2)")
552-
elif partials[1] in protected_kube_namespaces and allow_protected_ns is False:
553-
errors.append("service upstream is invalid (e3)")
554-
elif do_validate_upstreams and (partials[1] in perm_upstreams) is False:
555-
errors.append("service upstream is invalid (e6)")
556-
elif host.endswith('svc.cluster.local'):
557-
partials = host.split('.')
558-
# get the namespace, and make sure it is not in the protected_kube_namespaces list
559-
if len(partials) != 5:
560-
errors.append("service upstream is invalid (e4)")
561-
elif partials[1] in protected_kube_namespaces and allow_protected_ns is False:
562-
errors.append("service upstream is invalid (e5)")
563-
elif do_validate_upstreams and (partials[1] in perm_upstreams) is False:
564-
errors.append("service upstream is invalid (e6)")
565-
elif do_validate_upstreams:
566-
errors.append("service upstream is invalid (e6)")
567-
568512
def update_routes_check(yaml):
569513
if 'services' in yaml or 'upstreams' not in yaml:
570514
return True

0 commit comments

Comments
 (0)