Skip to content

Commit

Permalink
Add JWT Auth tests for mergeable and standard secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
tellet committed Apr 15, 2019
1 parent f2aeaf3 commit 4d18978
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tests/data/jwt-auth-mergeable/jwt-master-secret-updated.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Secret
metadata:
name: jwt-master-jwk
data:
jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJZWGRsYzI5dFpXcDNkQSIsCiAgICAgICAgImt0eSI6Im9jdCIsCiAgICAgICAgImtpZCI6IjAwMDEiCiAgICB9XQp9
6 changes: 6 additions & 0 deletions tests/data/jwt-auth-mergeable/jwt-master-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Secret
metadata:
name: jwt-master-jwk
apiVersion: v1
data:
jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJabUZ1ZEdGemRHbGphbmQwIiwKICAgICAgICAia3R5Ijoib2N0IiwKICAgICAgICAia2lkIjoiMDAwMSIKICAgIH1dCn0K
6 changes: 6 additions & 0 deletions tests/data/jwt-auth-mergeable/jwt-minion-secret-updated.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Secret
metadata:
name: jwt-minion-jwk
apiVersion: v1
data:
jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJabUZ1ZEdGemRHbGphbmQwIiwKICAgICAgICAia3R5Ijoib2N0IiwKICAgICAgICAia2lkIjoiMDAwMSIKICAgIH1dCn0K
6 changes: 6 additions & 0 deletions tests/data/jwt-auth-mergeable/jwt-minion-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Secret
metadata:
name: jwt-minion-jwk
data:
jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJZWGRsYzI5dFpXcDNkQSIsCiAgICAgICAgImt0eSI6Im9jdCIsCiAgICAgICAgImtpZCI6IjAwMDEiCiAgICB9XQp9
53 changes: 53 additions & 0 deletions tests/data/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-auth-ingress-master
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/mergeable-ingress-type: "master"
nginx.com/jwt-key: "jwt-master-jwk"
nginx.com/jwt-realm: "JWT Auth Mergeable App"
nginx.com/jwt-token: "$cookie_auth_token"
nginx.com/jwt-login-url: "https://login.jwt-auth-mergeable.example.com"
spec:
rules:
- host: jwt-auth-mergeable.example.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-auth-ingress-backend1-minion
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/mergeable-ingress-type: "minion"
nginx.com/jwt-key: "jwt-minion-jwk"
nginx.com/jwt-realm: "Backend1"
nginx.com/jwt-token: "$cookie_auth_token"
nginx.com/jwt-login-url: "https://login-backend1.jwt-auth-mergeable.example.com"
spec:
rules:
- host: jwt-auth-mergeable.example.com
http:
paths:
- path: /backend1
backend:
serviceName: backend1-svc
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-auth-ingress-backend2-minion
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/mergeable-ingress-type: "minion"
spec:
rules:
- host: jwt-auth-mergeable.example.com
http:
paths:
- path: /backend2
backend:
serviceName: backend2-svc
servicePort: 80
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEifQ.eyJuYW1lIjoiUXVvdGF0aW9uIFN5c3RlbSIsInN1YiI6InF1b3RlcyIsImlzcyI6Ik15IEFQSSBHYXRld2F5In0.ggVOHYnVFB8GVPE-VOIo3jD71gTkLffAY0hQOGXPL2I
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEifQ.eyJuYW1lIjoiUXVvdGF0aW9uIFN5c3RlbSIsInN1YiI6InF1b3RlcyIsImV4cCI6IjE1Nzc4MzY4MDAiLCJpc3MiOiJNeSBBUEkgR2F0ZXdheSJ9.UPkL_q1ChtHExgvKrnKCLDlWHXjVrprgaa79-ZT7qRo
6 changes: 6 additions & 0 deletions tests/data/jwt-secrets/jwt-secret-invalid.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Secret
metadata:
name: jwt-secrets-key
apiVersion: v1
data:
invalid-jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJabUZ1ZEdGemRHbGphbmQwIiwKICAgICAgICAia3R5Ijoib2N0IiwKICAgICAgICAia2lkIjoiMDAwMSIKICAgIH1dCn0K
6 changes: 6 additions & 0 deletions tests/data/jwt-secrets/jwt-secret-updated.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Secret
metadata:
name: jwt-secrets-key
data:
jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJZWGRsYzI5dFpXcDNkQSIsCiAgICAgICAgImt0eSI6Im9jdCIsCiAgICAgICAgImtpZCI6IjAwMDEiCiAgICB9XQp9
6 changes: 6 additions & 0 deletions tests/data/jwt-secrets/jwt-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Secret
metadata:
name: jwt-secrets-key
apiVersion: v1
data:
jwk: eyJrZXlzIjoKICAgIFt7CiAgICAgICAgImsiOiJabUZ1ZEdGemRHbGphbmQwIiwKICAgICAgICAia3R5Ijoib2N0IiwKICAgICAgICAia2lkIjoiMDAwMSIKICAgIH1dCn0K
48 changes: 48 additions & 0 deletions tests/data/jwt-secrets/mergeable/jwt-secrets-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-secrets-ingress-master
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/mergeable-ingress-type: "master"
spec:
rules:
- host: jwt-secrets.example.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-secrets-ingress-backend1-minion
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/mergeable-ingress-type: "minion"
spec:
rules:
- host: jwt-secrets.example.com
http:
paths:
- path: /backend1
backend:
serviceName: backend1-svc
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-secrets-ingress-backend2-minion
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/mergeable-ingress-type: "minion"
nginx.com/jwt-key: "jwt-secrets-key"
nginx.com/jwt-realm: "JWT Secrets App"
nginx.com/jwt-token: "$cookie_auth_token"
nginx.com/jwt-login-url: "https://login.jwt-secrets.example.com"
spec:
rules:
- host: jwt-secrets.example.com
http:
paths:
- path: /backend2
backend:
serviceName: backend2-svc
servicePort: 80
23 changes: 23 additions & 0 deletions tests/data/jwt-secrets/standard/jwt-secrets-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jwt-secrets-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.com/jwt-key: "jwt-secrets-key"
nginx.com/jwt-realm: "JWT Secrets App"
nginx.com/jwt-token: "$cookie_auth_token"
nginx.com/jwt-login-url: "https://login.jwt-secrets.example.com"
spec:
rules:
- host: "jwt-secrets.example.com"
http:
paths:
- path: /backend2
backend:
serviceName: backend2-svc
servicePort: 80
- path: /backend1
backend:
serviceName: backend1-svc
servicePort: 80
1 change: 1 addition & 0 deletions tests/data/jwt-secrets/tokens/jwt-secrets-token.jwt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEifQ.eyJuYW1lIjoiUXVvdGF0aW9uIFN5c3RlbSIsInN1YiI6InF1b3RlcyIsImlzcyI6Ik15IEFQSSBHYXRld2F5In0.ggVOHYnVFB8GVPE-VOIo3jD71gTkLffAY0hQOGXPL2I
157 changes: 157 additions & 0 deletions tests/suite/test_jwt_auth_mergeable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import requests
import pytest

from suite.fixtures import PublicEndpoint
from suite.resources_utils import create_secret_from_yaml, delete_secret, replace_secret, ensure_connection_to_public_endpoint, wait_before_test
from suite.resources_utils import create_items_from_yaml, delete_items_from_yaml, create_common_app, delete_common_app
from suite.resources_utils import get_ingress_host_from_yaml, wait_until_all_pods_are_containers_ready, is_secret_present
from settings import TEST_DATA


class JWTAuthMergeableSetup:
"""
Encapsulate JWT Auth Mergeable Minions Example details.
Attributes:
public_endpoint (PublicEndpoint):
ingress_host (str): a hostname from Ingress resource
master_secret_name (str):
minion_secret_name (str):
tokens ([]): a list of tokens for testing
"""
def __init__(self, public_endpoint: PublicEndpoint, ingress_host, master_secret_name, minion_secret_name, tokens):
self.public_endpoint = public_endpoint
self.ingress_host = ingress_host
self.master_secret_name = master_secret_name
self.minion_secret_name = minion_secret_name
self.tokens = tokens


@pytest.fixture(scope="class")
def jwt_auth_setup(request, kube_apis, ingress_controller_endpoint, ingress_controller, test_namespace) -> JWTAuthMergeableSetup:
tokens = {"master": get_token_from_file("master"), "minion": get_token_from_file("minion")}
master_secret_name = create_secret_from_yaml(kube_apis.v1, test_namespace,
f"{TEST_DATA}/jwt-auth-mergeable/jwt-master-secret.yaml")
minion_secret_name = create_secret_from_yaml(kube_apis.v1, test_namespace,
f"{TEST_DATA}/jwt-auth-mergeable/jwt-minion-secret.yaml")
print("------------------------- Deploy JWT Auth Mergeable Minions Example -----------------------------------")
create_items_from_yaml(kube_apis.extensions_v1_beta1, f"{TEST_DATA}/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml", test_namespace)
ingress_host = get_ingress_host_from_yaml(f"{TEST_DATA}/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml")
common_app = create_common_app(kube_apis.v1, kube_apis.extensions_v1_beta1, test_namespace)
wait_until_all_pods_are_containers_ready(kube_apis.v1, test_namespace)
ensure_connection_to_public_endpoint(ingress_controller_endpoint.public_ip,
ingress_controller_endpoint.port,
ingress_controller_endpoint.port_ssl)
wait_before_test(2)

def fin():
print("Delete Master Secret:")
if is_secret_present(kube_apis.v1, master_secret_name, test_namespace):
delete_secret(kube_apis.v1, master_secret_name, test_namespace)

print("Delete Minion Secret:")
if is_secret_present(kube_apis.v1, minion_secret_name, test_namespace):
delete_secret(kube_apis.v1, minion_secret_name, test_namespace)

print("Clean up the JWT Auth Mergeable Minions Application:")
delete_common_app(kube_apis.v1, kube_apis.extensions_v1_beta1, common_app, test_namespace)
delete_items_from_yaml(kube_apis.extensions_v1_beta1, f"{TEST_DATA}/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml",
test_namespace)

request.addfinalizer(fin)

return JWTAuthMergeableSetup(ingress_controller_endpoint, ingress_host, master_secret_name, minion_secret_name, tokens)


def get_token_from_file(token_type) -> str:
"""
Get token from the file.
:param token_type: 'master' or 'minion'
:return: str
"""
with open(f"{TEST_DATA}/jwt-auth-mergeable/tokens/jwt-auth-{token_type}-token.jwt", "r") as token_file:
return token_file.read().replace('\n', '')


step_1_expected_results = [{"token_type": "master", "path": "", "response_code": 404},
{"token_type": "master", "path": "backend1", "response_code": 302, "location": "https://login-backend1.jwt-auth-mergeable.example.com"},
{"token_type": "master", "path": "backend2", "response_code": 200},
{"token_type": "minion", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "minion", "path": "backend1", "response_code": 200},
{"token_type": "minion", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"}]

step_2_expected_results = [{"token_type": "master", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "master", "path": "backend1", "response_code": 302, "location": "https://login-backend1.jwt-auth-mergeable.example.com"},
{"token_type": "master", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "minion", "path": "", "response_code": 404},
{"token_type": "minion", "path": "backend1", "response_code": 200},
{"token_type": "minion", "path": "backend2", "response_code": 200}]

step_3_expected_results = [{"token_type": "master", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "master", "path": "backend1", "response_code": 200},
{"token_type": "master", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "minion", "path": "", "response_code": 404},
{"token_type": "minion", "path": "backend1", "response_code": 302, "location": "https://login-backend1.jwt-auth-mergeable.example.com"},
{"token_type": "minion", "path": "backend2", "response_code": 200}]

step_4_expected_results = [{"token_type": "master", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "master", "path": "backend1", "response_code": 500},
{"token_type": "master", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
{"token_type": "minion", "path": "", "response_code": 404},
{"token_type": "minion", "path": "backend1", "response_code": 500},
{"token_type": "minion", "path": "backend2", "response_code": 200}]

step_5_expected_results = [{"token_type": "master", "path": "", "response_code": 500},
{"token_type": "master", "path": "backend1", "response_code": 500},
{"token_type": "master", "path": "backend2", "response_code": 500},
{"token_type": "minion", "path": "", "response_code": 500},
{"token_type": "minion", "path": "backend1", "response_code": 500},
{"token_type": "minion", "path": "backend2", "response_code": 500}]


@pytest.mark.skip_for_nginx_oss
class TestJWTAuthMergeableMinions:
def test_jwt_auth_response_codes_and_location(self, kube_apis, jwt_auth_setup, test_namespace):
print("Step 1: execute check after secrets creation")
execute_checks(jwt_auth_setup, step_1_expected_results)

print("Step 2: replace master secret")
replace_secret(kube_apis.v1, jwt_auth_setup.master_secret_name, test_namespace,
f"{TEST_DATA}/jwt-auth-mergeable/jwt-master-secret-updated.yaml")
wait_before_test(1)
execute_checks(jwt_auth_setup, step_2_expected_results)

print("Step 3: now replace minion secret as well")
replace_secret(kube_apis.v1, jwt_auth_setup.minion_secret_name, test_namespace,
f"{TEST_DATA}/jwt-auth-mergeable/jwt-minion-secret-updated.yaml")
wait_before_test(1)
execute_checks(jwt_auth_setup, step_3_expected_results)

print("Step 4: now remove minion secret")
delete_secret(kube_apis.v1, jwt_auth_setup.minion_secret_name, test_namespace)
wait_before_test(1)
execute_checks(jwt_auth_setup, step_4_expected_results)

print("Step 5: finally remove master secret as well")
delete_secret(kube_apis.v1, jwt_auth_setup.master_secret_name, test_namespace)
wait_before_test(1)
execute_checks(jwt_auth_setup, step_5_expected_results)


def execute_checks(jwt_auth_setup, expected_results) -> None:
"""
Assert response code and location.
:param jwt_auth_setup: JWTAuthMergeableSetup
:param expected_results: an array of expected results
:return:
"""
for expected in expected_results:
req_url = f"http://{jwt_auth_setup.public_endpoint.public_ip}:{jwt_auth_setup.public_endpoint.port}/{expected['path']}"
resp = requests.get(req_url, headers={"host": jwt_auth_setup.ingress_host},
cookies={"auth_token": jwt_auth_setup.tokens[expected['token_type']]},
allow_redirects=False)
assert resp.status_code == expected['response_code']
if expected.get('location', None):
assert resp.headers['Location'] == expected['location']
Loading

0 comments on commit 4d18978

Please sign in to comment.