github.com/nginxinc/kubernetes-ingress@v1.12.5/tests/suite/test_v_s_route_error_pages.py (about) 1 import requests 2 import pytest 3 import json 4 5 from kubernetes.client.rest import ApiException 6 7 from settings import TEST_DATA 8 from suite.custom_assertions import wait_and_assert_status_code, \ 9 assert_event_starts_with_text_and_contains_errors 10 from suite.custom_resources_utils import get_vs_nginx_template_conf, patch_v_s_route_from_yaml, \ 11 patch_virtual_server_from_yaml 12 from suite.resources_utils import get_first_pod_name, get_events, wait_before_test 13 14 15 @pytest.mark.vsr 16 @pytest.mark.parametrize('crd_ingress_controller, v_s_route_setup', 17 [({"type": "complete", "extra_args": [f"-enable-custom-resources"]}, 18 {"example": "virtual-server-route-error-pages"})], 19 indirect=True) 20 class TestVSRErrorPages: 21 def test_redirect_strategy(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, 22 v_s_route_setup): 23 req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" 24 wait_and_assert_status_code(307, f"{req_url}{v_s_route_setup.route_m.paths[0]}", 25 v_s_route_setup.vs_host, allow_redirects=False) 26 resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[0]}", 27 headers={"host": v_s_route_setup.vs_host}, allow_redirects=False) 28 assert f'http://{v_s_route_setup.vs_host}/error.html' in resp.next.url 29 30 def test_return_strategy(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, 31 v_s_route_setup): 32 req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" 33 wait_and_assert_status_code(207, f"{req_url}{v_s_route_setup.route_m.paths[1]}", v_s_route_setup.vs_host) 34 resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[1]}", 35 headers={"host": v_s_route_setup.vs_host}) 36 resp_content = json.loads(resp.content) 37 assert resp_content['status'] == '502' \ 38 and resp_content['message'] == 'Forbidden' \ 39 and resp.headers.get('x-debug-original-status') == '502' 40 41 def test_virtual_server_after_update(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, 42 v_s_route_setup): 43 req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" 44 patch_v_s_route_from_yaml(kube_apis.custom_objects, 45 v_s_route_setup.route_m.name, 46 f"{TEST_DATA}/virtual-server-route-error-pages/route-multiple-updated.yaml", 47 v_s_route_setup.route_m.namespace) 48 wait_and_assert_status_code(301, f"{req_url}{v_s_route_setup.route_m.paths[0]}", 49 v_s_route_setup.vs_host, allow_redirects=False) 50 resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[0]}", 51 headers={"host": v_s_route_setup.vs_host, "x-forwarded-proto": "http"}, 52 allow_redirects=False) 53 assert f'http://{v_s_route_setup.vs_host}/error_http.html' in resp.next.url 54 55 wait_and_assert_status_code(502, f"{req_url}{v_s_route_setup.route_m.paths[1]}", 56 v_s_route_setup.vs_host, allow_redirects=False) 57 resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[1]}", 58 headers={"host": v_s_route_setup.vs_host}) 59 resp_content = resp.content.decode('utf-8') 60 assert resp_content == 'Hello World!\n' 61 62 def test_validation_event_flow(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, 63 v_s_route_setup): 64 invalid_fields_m = [ 65 "spec.subroutes[0].errorPages[0].redirect.url: Invalid value", 66 "spec.subroutes[0].errorPages[0].redirect.code: Invalid value: 101", 67 "spec.subroutes[1].errorPages[0].return.body: Invalid value: \"status\"", 68 "spec.subroutes[1].errorPages[0].return.code: Invalid value: 100", 69 "spec.subroutes[1].errorPages[0].return.headers[0].value: Invalid value: \"schema\"" 70 ] 71 invalid_fields_s = [ 72 "spec.subroutes[0].errorPages[0].redirect.url: Required value: must specify a url" 73 ] 74 text_s = f"{v_s_route_setup.route_s.namespace}/{v_s_route_setup.route_s.name}" 75 text_m = f"{v_s_route_setup.route_m.namespace}/{v_s_route_setup.route_m.name}" 76 vsr_s_event_text = f"VirtualServerRoute {text_s} was rejected with error:" 77 vsr_m_event_text = f"VirtualServerRoute {text_m} was rejected with error:" 78 patch_v_s_route_from_yaml(kube_apis.custom_objects, 79 v_s_route_setup.route_s.name, 80 f"{TEST_DATA}/virtual-server-route-error-pages/route-single-invalid.yaml", 81 v_s_route_setup.route_s.namespace) 82 patch_v_s_route_from_yaml(kube_apis.custom_objects, 83 v_s_route_setup.route_m.name, 84 f"{TEST_DATA}/virtual-server-route-error-pages/route-multiple-invalid.yaml", 85 v_s_route_setup.route_m.namespace) 86 wait_before_test(2) 87 ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace) 88 config = get_vs_nginx_template_conf(kube_apis.v1, 89 v_s_route_setup.namespace, 90 v_s_route_setup.vs_name, 91 ic_pod_name, 92 ingress_controller_prerequisites.namespace) 93 vsr_s_events = get_events(kube_apis.v1, v_s_route_setup.route_s.namespace) 94 vsr_m_events = get_events(kube_apis.v1, v_s_route_setup.route_m.namespace) 95 96 assert_event_starts_with_text_and_contains_errors(vsr_s_event_text, vsr_s_events, invalid_fields_s) 97 assert_event_starts_with_text_and_contains_errors(vsr_m_event_text, vsr_m_events, invalid_fields_m) 98 assert "upstream" not in config 99 100 def test_openapi_validation_flow(self, kube_apis, ingress_controller_prerequisites, 101 crd_ingress_controller, v_s_route_setup): 102 ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace) 103 config_old = get_vs_nginx_template_conf(kube_apis.v1, 104 v_s_route_setup.namespace, 105 v_s_route_setup.vs_name, 106 ic_pod_name, 107 ingress_controller_prerequisites.namespace) 108 vsr_src = f"{TEST_DATA}/virtual-server-route-error-pages/route-multiple-invalid-openapi.yaml" 109 try: 110 patch_v_s_route_from_yaml(kube_apis.custom_objects, 111 v_s_route_setup.route_m.name, 112 vsr_src, 113 v_s_route_setup.route_m.namespace) 114 except ApiException as ex: 115 assert ex.status == 422 \ 116 and "spec.subroutes.errorPages.codes" in ex.body \ 117 and "spec.subroutes.errorPages.redirect.code" in ex.body \ 118 and "spec.subroutes.errorPages.redirect.url" in ex.body \ 119 and "spec.subroutes.errorPages.return.code" in ex.body \ 120 and "spec.subroutes.errorPages.return.type" in ex.body \ 121 and "spec.subroutes.errorPages.return.body" in ex.body \ 122 and "spec.subroutes.errorPages.return.headers.name" in ex.body \ 123 and "spec.subroutes.errorPages.return.headers.value" in ex.body 124 except Exception as ex: 125 pytest.fail(f"An unexpected exception is raised: {ex}") 126 else: 127 pytest.fail("Expected an exception but there was none") 128 129 wait_before_test(1) 130 config_new = get_vs_nginx_template_conf(kube_apis.v1, 131 v_s_route_setup.namespace, 132 v_s_route_setup.vs_name, 133 ic_pod_name, 134 ingress_controller_prerequisites.namespace) 135 assert config_old == config_new, "Expected: config doesn't change" 136 137 @pytest.mark.parametrize('v_s_r_data', [ 138 {"src": "route-multiple-splits.yaml", "expected_code": 308}, 139 {"src": "route-multiple-matches.yaml", "expected_code": 307} 140 ]) 141 def test_splits_and_matches(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, 142 v_s_route_setup, v_s_r_data): 143 req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" 144 patch_v_s_route_from_yaml(kube_apis.custom_objects, 145 v_s_route_setup.route_m.name, 146 f"{TEST_DATA}/virtual-server-route-error-pages/{v_s_r_data['src']}", 147 v_s_route_setup.route_m.namespace) 148 wait_and_assert_status_code(v_s_r_data["expected_code"], f"{req_url}{v_s_route_setup.route_m.paths[0]}", 149 v_s_route_setup.vs_host, allow_redirects=False) 150 resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[0]}", 151 headers={"host": v_s_route_setup.vs_host}, allow_redirects=False) 152 assert f'http://{v_s_route_setup.vs_host}/error.html' in resp.next.url 153 154 def test_vsr_overrides_vs(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, 155 v_s_route_setup): 156 req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" 157 vs_src = f"{TEST_DATA}/virtual-server-route-error-pages/standard/virtual-server-updated.yaml" 158 patch_virtual_server_from_yaml(kube_apis.custom_objects, 159 v_s_route_setup.vs_name, 160 vs_src, 161 v_s_route_setup.namespace) 162 patch_v_s_route_from_yaml(kube_apis.custom_objects, 163 v_s_route_setup.route_m.name, 164 f"{TEST_DATA}/virtual-server-route-error-pages/route-multiple.yaml", 165 v_s_route_setup.route_m.namespace) 166 wait_and_assert_status_code(307, f"{req_url}{v_s_route_setup.route_m.paths[0]}", 167 v_s_route_setup.vs_host, allow_redirects=False) 168 resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[0]}", 169 headers={"host": v_s_route_setup.vs_host}, allow_redirects=False) 170 assert f'http://{v_s_route_setup.vs_host}/error.html' in resp.next.url