github.com/nginxinc/kubernetes-ingress@v1.12.5/tests/suite/test_jwt_auth_mergeable.py (about)

     1  import requests
     2  import pytest
     3  
     4  from suite.fixtures import PublicEndpoint
     5  from suite.resources_utils import create_secret_from_yaml, delete_secret, replace_secret,\
     6      ensure_connection_to_public_endpoint, wait_before_test
     7  from suite.resources_utils import create_items_from_yaml, delete_items_from_yaml, create_example_app, delete_common_app
     8  from suite.resources_utils import wait_until_all_pods_are_ready, is_secret_present
     9  from suite.yaml_utils import get_first_ingress_host_from_yaml
    10  from settings import TEST_DATA
    11  
    12  
    13  class JWTAuthMergeableSetup:
    14      """
    15      Encapsulate JWT Auth Mergeable Minions Example details.
    16  
    17      Attributes:
    18          public_endpoint (PublicEndpoint):
    19          ingress_host (str): a hostname from Ingress resource
    20          master_secret_name (str):
    21          minion_secret_name (str):
    22          tokens ([]): a list of tokens for testing
    23      """
    24      def __init__(self, public_endpoint: PublicEndpoint, ingress_host, master_secret_name, minion_secret_name, tokens):
    25          self.public_endpoint = public_endpoint
    26          self.ingress_host = ingress_host
    27          self.master_secret_name = master_secret_name
    28          self.minion_secret_name = minion_secret_name
    29          self.tokens = tokens
    30  
    31  
    32  @pytest.fixture(scope="class")
    33  def jwt_auth_setup(request, kube_apis, ingress_controller_endpoint, ingress_controller, test_namespace) -> JWTAuthMergeableSetup:
    34      tokens = {"master": get_token_from_file("master"), "minion": get_token_from_file("minion")}
    35      master_secret_name = create_secret_from_yaml(kube_apis.v1, test_namespace,
    36                                                   f"{TEST_DATA}/jwt-auth-mergeable/jwt-master-secret.yaml")
    37      minion_secret_name = create_secret_from_yaml(kube_apis.v1, test_namespace,
    38                                                   f"{TEST_DATA}/jwt-auth-mergeable/jwt-minion-secret.yaml")
    39      print("------------------------- Deploy JWT Auth Mergeable Minions Example -----------------------------------")
    40      create_items_from_yaml(kube_apis, f"{TEST_DATA}/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml", test_namespace)
    41      ingress_host = get_first_ingress_host_from_yaml(f"{TEST_DATA}/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml")
    42      create_example_app(kube_apis, "simple", test_namespace)
    43      wait_until_all_pods_are_ready(kube_apis.v1, test_namespace)
    44      ensure_connection_to_public_endpoint(ingress_controller_endpoint.public_ip,
    45                                           ingress_controller_endpoint.port,
    46                                           ingress_controller_endpoint.port_ssl)
    47      wait_before_test(2)
    48  
    49      def fin():
    50          print("Delete Master Secret:")
    51          if is_secret_present(kube_apis.v1, master_secret_name, test_namespace):
    52              delete_secret(kube_apis.v1, master_secret_name, test_namespace)
    53  
    54          print("Delete Minion Secret:")
    55          if is_secret_present(kube_apis.v1, minion_secret_name, test_namespace):
    56              delete_secret(kube_apis.v1, minion_secret_name, test_namespace)
    57  
    58          print("Clean up the JWT Auth Mergeable Minions Application:")
    59          delete_common_app(kube_apis, "simple", test_namespace)
    60          delete_items_from_yaml(kube_apis, f"{TEST_DATA}/jwt-auth-mergeable/mergeable/jwt-auth-ingress.yaml",
    61                                 test_namespace)
    62  
    63      request.addfinalizer(fin)
    64  
    65      return JWTAuthMergeableSetup(ingress_controller_endpoint, ingress_host, master_secret_name, minion_secret_name, tokens)
    66  
    67  
    68  def get_token_from_file(token_type) -> str:
    69      """
    70      Get token from the file.
    71  
    72      :param token_type: 'master' or 'minion'
    73      :return: str
    74      """
    75      with open(f"{TEST_DATA}/jwt-auth-mergeable/tokens/jwt-auth-{token_type}-token.jwt", "r") as token_file:
    76          return token_file.read().replace('\n', '')
    77  
    78  
    79  step_1_expected_results = [{"token_type": "master", "path": "", "response_code": 404},
    80                             {"token_type": "master", "path": "backend1", "response_code": 302, "location": "https://login-backend1.jwt-auth-mergeable.example.com"},
    81                             {"token_type": "master", "path": "backend2", "response_code": 200},
    82                             {"token_type": "minion", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
    83                             {"token_type": "minion", "path": "backend1", "response_code": 200},
    84                             {"token_type": "minion", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"}]
    85  
    86  step_2_expected_results = [{"token_type": "master", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
    87                             {"token_type": "master", "path": "backend1", "response_code": 302, "location": "https://login-backend1.jwt-auth-mergeable.example.com"},
    88                             {"token_type": "master", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
    89                             {"token_type": "minion", "path": "", "response_code": 404},
    90                             {"token_type": "minion", "path": "backend1", "response_code": 200},
    91                             {"token_type": "minion", "path": "backend2", "response_code": 200}]
    92  
    93  step_3_expected_results = [{"token_type": "master", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
    94                             {"token_type": "master", "path": "backend1", "response_code": 200},
    95                             {"token_type": "master", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
    96                             {"token_type": "minion", "path": "", "response_code": 404},
    97                             {"token_type": "minion", "path": "backend1", "response_code": 302, "location": "https://login-backend1.jwt-auth-mergeable.example.com"},
    98                             {"token_type": "minion", "path": "backend2", "response_code": 200}]
    99  
   100  step_4_expected_results = [{"token_type": "master", "path": "", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
   101                             {"token_type": "master", "path": "backend1", "response_code": 500},
   102                             {"token_type": "master", "path": "backend2", "response_code": 302, "location": "https://login.jwt-auth-mergeable.example.com"},
   103                             {"token_type": "minion", "path": "", "response_code": 404},
   104                             {"token_type": "minion", "path": "backend1", "response_code": 500},
   105                             {"token_type": "minion", "path": "backend2", "response_code": 200}]
   106  
   107  step_5_expected_results = [{"token_type": "master", "path": "", "response_code": 500},
   108                             {"token_type": "master", "path": "backend1", "response_code": 500},
   109                             {"token_type": "master", "path": "backend2", "response_code": 500},
   110                             {"token_type": "minion", "path": "", "response_code": 500},
   111                             {"token_type": "minion", "path": "backend1", "response_code": 500},
   112                             {"token_type": "minion", "path": "backend2", "response_code": 500}]
   113  
   114  
   115  @pytest.mark.ingresses
   116  @pytest.mark.skip_for_nginx_oss
   117  class TestJWTAuthMergeableMinions:
   118      def test_jwt_auth_response_codes_and_location(self, kube_apis, jwt_auth_setup, test_namespace):
   119          print("Step 1: execute check after secrets creation")
   120          execute_checks(jwt_auth_setup, step_1_expected_results)
   121  
   122          print("Step 2: replace master secret")
   123          replace_secret(kube_apis.v1, jwt_auth_setup.master_secret_name, test_namespace,
   124                         f"{TEST_DATA}/jwt-auth-mergeable/jwt-master-secret-updated.yaml")
   125          wait_before_test(1)
   126          execute_checks(jwt_auth_setup, step_2_expected_results)
   127  
   128          print("Step 3: now replace minion secret as well")
   129          replace_secret(kube_apis.v1, jwt_auth_setup.minion_secret_name, test_namespace,
   130                         f"{TEST_DATA}/jwt-auth-mergeable/jwt-minion-secret-updated.yaml")
   131          wait_before_test(1)
   132          execute_checks(jwt_auth_setup, step_3_expected_results)
   133  
   134          print("Step 4: now remove minion secret")
   135          delete_secret(kube_apis.v1, jwt_auth_setup.minion_secret_name, test_namespace)
   136          wait_before_test(1)
   137          execute_checks(jwt_auth_setup, step_4_expected_results)
   138  
   139          print("Step 5: finally remove master secret as well")
   140          delete_secret(kube_apis.v1, jwt_auth_setup.master_secret_name, test_namespace)
   141          wait_before_test(1)
   142          execute_checks(jwt_auth_setup, step_5_expected_results)
   143  
   144  
   145  def execute_checks(jwt_auth_setup, expected_results) -> None:
   146      """
   147      Assert response code and location.
   148  
   149      :param jwt_auth_setup: JWTAuthMergeableSetup
   150      :param expected_results: an array of expected results
   151      :return:
   152      """
   153      for expected in expected_results:
   154          req_url = f"http://{jwt_auth_setup.public_endpoint.public_ip}:{jwt_auth_setup.public_endpoint.port}/{expected['path']}"
   155          resp = requests.get(req_url, headers={"host": jwt_auth_setup.ingress_host},
   156                              cookies={"auth_token": jwt_auth_setup.tokens[expected['token_type']]},
   157                              allow_redirects=False)
   158          assert resp.status_code == expected['response_code']
   159          if expected.get('location', None):
   160              assert resp.headers['Location'] == expected['location']