Skip to content

Commit

Permalink
upd gateway tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ikethecoder committed May 21, 2024
1 parent 4da2829 commit f21d328
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 8 deletions.
12 changes: 11 additions & 1 deletion microservices/gatewayApi/config/test.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"logLevel": "DEBUG",
"defaultDataPlane": "test-dp",
"defaultDataPlane": "test-default-dp",
"kongAdminUrl": "http://kong",
"portal": {
"url": "http://portal"
Expand All @@ -14,5 +14,15 @@
},
"hostTransformation": {
"enabled": false
},
"data_planes": {
"test-default-dp": {
"kube-api": "http://kube-api",
"kube-ns": "abcd-1234"
}
},
"kubeApiCreds": {
"kubeApiPass": "password",
"kubeApiUser": "username"
}
}
47 changes: 45 additions & 2 deletions microservices/gatewayApi/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def app(mocker):
mock_kong(mocker)
mock_portal_feeder(mocker)
mock_deck(mocker)
mock_kubeapi(mocker)

#mocker.patch("auth.authz.enforce_authorization", return_value=True)

Expand Down Expand Up @@ -67,7 +68,7 @@ def get_group_by_path(path, search_in_subgroups):
def get_group(id):
return {
"attributes": {

"perm-domains": [ ".api.gov.bc.ca", ".cluster.local" ]
}
}
mocker.patch("v2.services.namespaces.admin_api", return_value=mock_kc_admin)
Expand All @@ -76,13 +77,30 @@ def mock_kong(mocker):

def mock_requests_get(path):
if (path == 'http://kong/routes'):
class Response:
def json():
return {
"data": [
{
"name": "ns1-route",
"tags": [ "ns.ns1" ],
"hosts": [
"ns1-service.api.gov.bc.ca"
]
}
],
"next": None
}
return Response
elif (path == 'http://kong/certificates?tags=gwa.ns.mytest'):
class Response:
def json():
return {
"data": [],
"next": None
}
return Response

else:
raise Exception(path)
mocker.patch("clients.kong.requests.get", mock_requests_get)
Expand Down Expand Up @@ -115,4 +133,29 @@ def communicate(self):
returncode = 0

mock_output = "Deck reported no changes"
mocker.patch("v2.routes.gateway.Popen", return_value=mock_popen_instance(mock_output))
mocker.patch("v2.routes.gateway.Popen", return_value=mock_popen_instance(mock_output))

def mock_kubeapi(mocker):

def mock_requests_put(self, url, data=None, **kwargs):
if (url == 'http://kube-api/namespaces/mytest/routes'):
class Response:
status_code = 201
# def json():
# return {}
return Response
else:
raise Exception(url)

def mock_requests_get(self, url, **kwards):
if (url == 'http://kube-api/namespaces/mytest/local_tls'):
class Response:
status_code = 200
def json():
return {}
return Response
else:
raise Exception(url)

mocker.patch("clients.portal.requests.Session.put", mock_requests_put)
mocker.patch("clients.portal.requests.Session.get", mock_requests_get)
49 changes: 48 additions & 1 deletion microservices/gatewayApi/tests/routes/v2/test_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tests.testutils import trimleft
from unittest import mock

def test_happy_gateway_call(client):
def test_happy_dryrun_gateway_call(client):
configFile = '''
services:
- name: my-service
Expand All @@ -27,3 +27,50 @@ def test_happy_gateway_call(client):
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 200
assert json.dumps(response.json) == '{"message": "Dry-run. No changes applied.", "results": "Deck reported no changes"}'

def test_happy_dryrun_with_qualifier_gateway_call(client):
configFile = '''
services:
- name: my-service
host: myupstream.local
tags: ["ns.mytest.dev", "another"]
routes:
- name: route-1
hosts: [ myapi.api.gov.bc.ca ]
tags: ["ns.mytest.dev", "another2"]
plugins:
- name: acl-auth
tags: ["ns.mytest.dev"]
'''

data={
"configFile": configFile,
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 200
assert json.dumps(response.json) == '{"message": "Dry-run. No changes applied.", "results": "Deck reported no changes"}'


def test_happy_sync_gateway_call(client):
configFile = '''
services:
- name: my-service
host: myupstream.local
tags: ["ns.mytest", "another"]
routes:
- name: route-1
hosts: [ myapi.api.gov.bc.ca ]
tags: ["ns.mytest", "another2"]
plugins:
- name: acl-auth
tags: ["ns.mytest"]
'''

data={
"configFile": configFile,
"dryRun": False
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 200
assert json.dumps(response.json) == '{"message": "Sync successful.", "results": "Deck reported no changes"}'
33 changes: 33 additions & 0 deletions microservices/gatewayApi/tests/routes/v2/test_gateway_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import yaml
import pytest
import json
from v1.routes.gateway import validate_upstream
from tests.testutils import trimleft
from unittest import mock

def test_error_call_with_missing_config(client):
data={
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Missing input"}'


def test_error_call_with_empty_config(client):
data={
"configFile": '',
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Missing input"}'

def test_success_call_with_empty_document(client):
data={
"configFile": '---',
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 200
assert json.dumps(response.json) == '{"message": "Dry-run. No changes applied.", "results": "Deck reported no changes"}'
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ def test_missing_required_tag(client):
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Validation Errors:\\n.services.my-service missing required tag ns.mytest\\n.services.my-service invalid ns tag ns.mytest-invalid"}'

def test_conflicting_qualifier(client):
configFile = '''
services:
- name: my-service
host: myupstream.local
tags: ["ns.mytest.dev", "another"]
routes:
- name: route-1
hosts: [ myapi.api.gov.bc.ca ]
tags: ["ns.mytest.dev", "another2"]
plugins:
- name: acl-auth
tags: ["ns.mytest.prod"]
'''

data={
"configFile": configFile,
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Validation Errors:\\nToo many different qualified namespaces ([\'ns.mytest.dev\', \'ns.mytest.prod\']). Rejecting request."}'


def test_invalid_host(client):
configFile = '''
services:
Expand All @@ -49,5 +73,44 @@ def test_invalid_host(client):
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Validation Errors:\\nHost invalid: route-1 myapi.invalid.site. Route hosts must end with one of [.api.gov.bc.ca] for this namespace."}'
assert json.dumps(response.json) == '{"error": "Validation Errors:\\nHost invalid: route-1 myapi.invalid.site. Route hosts must end with one of [.api.gov.bc.ca,.cluster.local] for this namespace."}'


def test_conflicting_host(client):
configFile = '''
services:
- name: my-service
host: myupstream.local
tags: ["ns.mytest", "another"]
routes:
- name: route-1
hosts: [ ns1-service.api.gov.bc.ca ]
tags: ["ns.mytest", "another2"]
plugins:
- name: acl-auth
tags: ["ns.mytest"]
'''

data={
"configFile": configFile,
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Validation Errors:\\nservice.my-service.route.route-1 The host is already used in another namespace \'ns1-service.api.gov.bc.ca\'"}'

def test_invalid_upstream(client):
configFile = '''
services:
- name: my-service
host: localhost
tags: ["ns.mytest", "another"]
'''

data={
"configFile": configFile,
"dryRun": True
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 400
assert json.dumps(response.json) == '{"error": "Validation Errors:\\nservice upstream is invalid (e1)"}'
29 changes: 29 additions & 0 deletions microservices/gatewayApi/tests/routes/v2/test_gateway_local.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import yaml
import pytest
import json
from v1.routes.gateway import validate_upstream
from tests.testutils import trimleft
from unittest import mock

def test_local_host(client):
configFile = '''
services:
- name: my-service
host: myupstream.local
tags: ["ns.mytest", "another"]
routes:
- name: route-1
hosts: [ myapi.cluster.local ]
tags: ["ns.mytest", "another2"]
plugins:
- name: acl-auth
tags: ["ns.mytest"]
'''

data={
"configFile": configFile,
"dryRun": False
}
response = client.put('/v2/namespaces/mytest/gateway', json=data)
assert response.status_code == 200
assert json.dumps(response.json) == '{"message": "Sync successful.", "results": "Deck reported no changes"}'
7 changes: 4 additions & 3 deletions microservices/gatewayApi/v2/routes/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ def write_config(namespace: str) -> object:
dry_run = request.values['dryRun']
if "qualifier" in request.values:
select_tag_qualifier = request.values['qualifier']
elif request.content_type.startswith("application/json") and not request.json['configFile'] in [None, '']:
elif request.content_type.startswith("application/json") \
and 'configFile' in request.json \
and not request.json['configFile'] in [None, '']:
dfile = request.json['configFile']
dry_run = request.json['dryRun']
if "qualifier" in request.json:
Expand Down Expand Up @@ -483,8 +485,7 @@ def has_namespace_local_host_permission (ns_attributes):

# Validate transformed host: <service>.<namespace>.svc.cluster.local
def validate_local_host(host):
if is_host_local(host):
if len(host.split('.')) != 5:
if is_host_local(host) and len(host.split('.')) != 5:
return False
return True

Expand Down

0 comments on commit f21d328

Please sign in to comment.