def test_status_invalid( self, kube_apis, crd_ingress_controller, virtual_server_setup, ): """ Test VirtualServer status with a invalid path pattern """ patch_src = f"{TEST_DATA}/virtual-server-status/invalid-state.yaml" patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, patch_src, virtual_server_setup.namespace, ) wait_before_test() response = read_crd( kube_apis.custom_objects, virtual_server_setup.namespace, "virtualservers", virtual_server_setup.vs_name, ) self.patch_valid_vs(kube_apis, virtual_server_setup) assert (response["status"] and response["status"]["reason"] == "Rejected" and response["status"]["state"] == "Invalid")
def test_event_message_and_config(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): invalid_fields = [ "upstreams[0].lb-method", "upstreams[0].fail-timeout", "upstreams[0].max-fails", "upstreams[0].connect-timeout", "upstreams[0].read-timeout", "upstreams[0].send-timeout", "upstreams[0].keepalive" ] text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}" vs_event_text = f"VirtualServer {text} is invalid and was rejected: " vs_file = f"{TEST_DATA}/virtual-server-upstream-options/virtual-server-with-invalid-keys.yaml" patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, vs_file, virtual_server_setup.namespace) wait_before_test(2) ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) response = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) vs_events = get_events(kube_apis.v1, virtual_server_setup.namespace) assert_event_starts_with_text_and_contains_errors( vs_event_text, vs_events, invalid_fields) assert_template_config_does_not_exist(response)
def test_flow_with_complex_conditions(self, kube_apis, crd_ingress_controller, virtual_server_setup): patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-advanced-routing/virtual-server-complex.yaml", virtual_server_setup.namespace) wait_before_test(1) resp_1 = requests.get(virtual_server_setup.backend_1_url + "?arg1=v1", headers={ "host": virtual_server_setup.vs_host, "x-version": "future" }, cookies={"user": "******"}) resp_2 = requests.post(virtual_server_setup.backend_1_url + "?arg1=v2", headers={ "host": virtual_server_setup.vs_host, "x-version": "deprecated" }, cookies={"user": "******"}) resp_3 = requests.get(virtual_server_setup.backend_1_url + "?arg1=v2", headers={ "host": virtual_server_setup.vs_host, "x-version": "deprecated" }, cookies={"user": "******"}) execute_assertions(resp_1, resp_2, resp_3)
def test_invalid_value_rejection(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) initial_events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-upstream-tls/virtual-server-invalid.yaml", virtual_server_setup.namespace) wait_before_test(1) config = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_2 = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}) new_events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) proxy_host = f"vs_{virtual_server_setup.namespace}_{virtual_server_setup.vs_name}" assert f'proxy_pass https://{proxy_host}_backend1' not in config assert f'proxy_pass https://{proxy_host}_backend2' in config assert_response_codes(resp_1, resp_2) assert_no_new_events(initial_events_vs, new_events_vs)
def test_virtual_server_after_update(self, kube_apis, crd_ingress_controller, virtual_server_setup): patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-error-pages/virtual-server-updated.yaml", virtual_server_setup.namespace) wait_and_assert_status_code(301, virtual_server_setup.backend_1_url, virtual_server_setup.vs_host, allow_redirects=False) resp = requests.get(virtual_server_setup.backend_1_url, headers={ "host": virtual_server_setup.vs_host, "x-forwarded-proto": "http" }, allow_redirects=False) assert f'http://{virtual_server_setup.vs_host}/error_http.html' in resp.next.url wait_and_assert_status_code(502, virtual_server_setup.backend_2_url, virtual_server_setup.vs_host) resp = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}) resp_content = resp.content.decode('utf-8') assert resp_content == 'Hello World!\n'
def test_when_option_in_config_map_only( self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup, restore_configmap, config_map_file, expected_strings, unexpected_strings): text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}" vs_event_text = f"Configuration for {text} was added or updated" print(f"Case 3: key specified in ConfigMap, no option in VS") patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-upstream-options/standard/virtual-server.yaml", virtual_server_setup.namespace) config_map_name = ingress_controller_prerequisites.config_map[ "metadata"]["name"] replace_configmap_from_yaml(kube_apis.v1, config_map_name, ingress_controller_prerequisites.namespace, config_map_file) wait_before_test(1) ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) config = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_2 = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}) vs_events = get_events(kube_apis.v1, virtual_server_setup.namespace) assert_event(vs_event_text, vs_events) for _ in expected_strings: assert _ in config for _ in unexpected_strings: assert _ not in config assert_response_codes(resp_1, resp_2)
def test_status_warning( self, kube_apis, crd_ingress_controller, virtual_server_setup, ): """ Test VirtualServer status with conflicting Upstream fields Only for N+ since Slow-start isn """ patch_src = f"{TEST_DATA}/virtual-server-status/warning-state.yaml" patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, patch_src, virtual_server_setup.namespace, ) wait_before_test() response = read_crd( kube_apis.custom_objects, virtual_server_setup.namespace, "virtualservers", virtual_server_setup.vs_name, ) assert (response["status"] and response["status"]["reason"] == "AddedOrUpdatedWithWarning" and response["status"]["state"] == "Warning")
def test_openapi_validation_flow(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) config_old = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) vs_src = f"{TEST_DATA}/virtual-server-canned-responses/virtual-server-invalid-openapi.yaml" try: patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, vs_src, virtual_server_setup.namespace) except ApiException as ex: assert ex.status == 422 \ and "spec.routes.action.return.type" in ex.body \ and "spec.routes.action.return.body" in ex.body \ and "spec.routes.action.return.code" in ex.body except Exception as ex: pytest.fail(f"An unexpected exception is raised: {ex}") else: pytest.fail("Expected an exception but there was none") wait_before_test(1) config_new = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) assert config_old == config_new, "Expected: config doesn't change"
def test_update(self, kube_apis, crd_ingress_controller, virtual_server_setup): wait_before_test(1) text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}" vs_event_text = f"Configuration for {text} was added or updated" events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) initial_count = assert_event_and_get_count(vs_event_text, events_vs) vs_src = f"{TEST_DATA}/virtual-server-canned-responses/virtual-server-updated.yaml" patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, vs_src, virtual_server_setup.namespace) wait_and_assert_status_code(501, virtual_server_setup.backend_1_url, virtual_server_setup.vs_host) resp = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_content = resp.content.decode('utf-8') assert resp.headers[ 'content-type'] == 'some/type' and resp_content == "{}" wait_and_assert_status_code(201, virtual_server_setup.backend_2_url, virtual_server_setup.vs_host) resp = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}) resp_content = resp.content.decode('utf-8') assert resp.headers[ 'content-type'] == 'user-type' and resp_content == "line1\nline2" vs_events = get_events(kube_apis.v1, virtual_server_setup.namespace) assert_event_count_increased(vs_event_text, initial_count, vs_events)
def test_responses_and_config_after_disable_tls( self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}" vs_event_text = f"Configuration for {text} was added or updated" initial_events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) initial_count = assert_event_and_get_count(vs_event_text, initial_events_vs) patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-upstream-tls/virtual-server-disable-tls.yaml", virtual_server_setup.namespace) wait_before_test(1) config = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_2 = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}) new_events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) assert 'proxy_pass https://' not in config assert_response_codes(resp_1, resp_2, 200, 400) assert_event_count_increased(vs_event_text, initial_count, new_events_vs)
def test_rl_policy_deleted( self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, src, ): """ Test the status code if 500 is valid policy is removed """ print(f"Create rl policy") pol_name = create_policy_from_yaml(kube_apis.custom_objects, rl_pol_pri_src, test_namespace) print(f"Patch vs with policy: {src}") patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, src, virtual_server_setup.namespace, ) wait_before_test() resp = requests.get( virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, ) assert resp.status_code == 200 delete_policy(kube_apis.custom_objects, pol_name, test_namespace) wait_before_test() resp = requests.get( virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, ) self.restore_default_vs(kube_apis, virtual_server_setup) assert resp.status_code == 500
def test_tls_redirect_defaults(self, kube_apis, crd_ingress_controller, virtual_server_setup): patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-tls-redirect/virtual-server-default-redirect.yaml", virtual_server_setup.namespace) wait_before_test(1) resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) resp_2 = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) assert resp_1.status_code == 301, "Expected: a redirect for scheme=http" assert resp_2.status_code == 301, "Expected: a redirect for scheme=http" resp_3 = requests.get(virtual_server_setup.backend_1_url_ssl, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False, verify=False) resp_4 = requests.get(virtual_server_setup.backend_2_url_ssl, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False, verify=False) assert resp_3.status_code == 200, "Expected: no redirect for scheme=https" assert resp_4.status_code == 200, "Expected: no redirect for scheme=https"
def test_validation_event_flow(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): invalid_fields = [ "spec.routes[0].errorPages[0].redirect.url: Invalid value", "spec.routes[0].errorPages[0].redirect.code: Invalid value: 101", "spec.routes[1].errorPages[0].return.body: Invalid value: \"status\"", "spec.routes[1].errorPages[0].return.code: Invalid value: 100", "spec.routes[1].errorPages[0].return.headers[0].value: Invalid value: \"schema\"" ] text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}" vs_event_text = f"VirtualServer {text} was rejected with error:" vs_file = f"{TEST_DATA}/virtual-server-error-pages/virtual-server-invalid.yaml" patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, vs_file, virtual_server_setup.namespace) wait_before_test(2) ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) vs_events = get_events(kube_apis.v1, virtual_server_setup.namespace) assert_event_starts_with_text_and_contains_errors( vs_event_text, vs_events, invalid_fields) assert_vs_conf_not_exists(kube_apis, ic_pod_name, ingress_controller_prerequisites.namespace, virtual_server_setup)
def test_response_for_regex_location(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, v_s_route_setup, v_s_route_app_setup, test_data): req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" vs_src_yaml = f"{TEST_DATA}" \ f"/virtual-server-route-regexp-location/standard/virtual-server-{test_data['regex_type']}.yaml" vsr_src_yaml = f"{TEST_DATA}/virtual-server-route-regexp-location/route-single-{test_data['regex_type']}.yaml" patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name, vs_src_yaml, v_s_route_setup.namespace) patch_v_s_route_from_yaml(kube_apis.custom_objects, v_s_route_setup.route_s.name, vsr_src_yaml, v_s_route_setup.route_s.namespace) wait_before_test(1) for item in test_data['expected_results']: uri = item expected_code = test_data['expected_results'][uri] ensure_response_from_backend(f"{req_url}{uri}", v_s_route_setup.vs_host) resp = requests.get(f"{req_url}{uri}", headers={"host": v_s_route_setup.vs_host}) if expected_code == 200: assert resp.status_code == expected_code and "Server name: backend2-" in resp.text else: assert resp.status_code == expected_code, "Expected 404 for URI that doesn't match"
def test_regex_rewrite( self, kube_apis, crd_ingress_controller, virtual_server_setup, ): """ Test VirtualServer URI rewrite using regex """ patch_src = f"{TEST_DATA}/virtual-server-rewrites/virtual-server-rewrite-regex.yaml" patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, patch_src, virtual_server_setup.namespace, ) wait_before_test() resp1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp2 = requests.get(virtual_server_setup.backend_1_url+"/", headers={"host": virtual_server_setup.vs_host}) resp3 = requests.get(virtual_server_setup.backend_2_url+"/abc", headers={"host": virtual_server_setup.vs_host}) self.patch_standard_vs(kube_apis, virtual_server_setup) assert ("URI: /\nRequest" in resp1.text and "URI: /\nRequest" in resp2.text and "URI: /abc\nRequest" in resp3.text)
def test_validation_flow(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) initial_events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) try: patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-upstream-tls/virtual-server-invalid.yaml", virtual_server_setup.namespace) except ApiException as ex: assert ex.status == 422 and "spec.upstreams.tls.enable" in ex.body except Exception as ex: pytest.fail(f"An unexpected exception is raised: {ex}") else: pytest.fail("Expected an exception but there was none") wait_before_test(1) config = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_2 = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}) new_events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) proxy_host = f"vs_{virtual_server_setup.namespace}_{virtual_server_setup.vs_name}" assert f'proxy_pass https://{proxy_host}_backend1' not in config assert f'proxy_pass https://{proxy_host}_backend2' in config assert_response_codes(resp_1, resp_2) assert_no_new_events(initial_events_vs, new_events_vs)
def test_flow_for_invalid_vsr(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, v_s_route_setup, v_s_route_app_setup): ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace) text_vs = f"{v_s_route_setup.namespace}/{v_s_route_setup.vs_name}" text_vsr_s = f"{v_s_route_setup.route_m.namespace}/{v_s_route_setup.route_m.name}" vs_event_text = f'Configuration for {text_vs} was added or updated with warning(s)' vsr_event_text = f'VirtualServerRoute {text_vsr_s} was rejected with error: ' \ f'spec.subroutes[1].path: Duplicate value: "=/backends/exact-match$request"' vs_src_yaml = f"{TEST_DATA}" \ f"/virtual-server-route-regexp-location/standard/virtual-server-exact.yaml" patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name, vs_src_yaml, v_s_route_setup.namespace) vsr_src_yaml = f"{TEST_DATA}" \ f"/virtual-server-route-regexp-location/route-multiple-invalid-multiple-regexp-subroutes.yaml" patch_v_s_route_from_yaml(kube_apis.custom_objects, v_s_route_setup.route_m.name, vsr_src_yaml, v_s_route_setup.route_m.namespace) wait_before_test(2) config = get_vs_nginx_template_conf(kube_apis.v1, v_s_route_setup.namespace, v_s_route_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) ns_events = get_events(kube_apis.v1, v_s_route_setup.route_m.namespace) assert_event(vsr_event_text, ns_events) and assert_event(vs_event_text, ns_events) assert "location =/backends/exact-match$request {" not in config
def test_tls_redirect_based_on_scheme(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-tls-redirect/virtual-server-scheme-redirect.yaml", virtual_server_setup.namespace) wait_before_test(1) ic_pod_name = get_first_pod_name(kube_apis.v1, ingress_controller_prerequisites.namespace) config = get_vs_nginx_template_conf(kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) assert "proxy_set_header X-Forwarded-Proto $scheme;" in config resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) resp_2 = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) assert resp_1.status_code == 302, "Expected: a redirect for scheme=http" assert resp_2.status_code == 302, "Expected: a redirect for scheme=http" resp_3 = requests.get(virtual_server_setup.backend_1_url_ssl, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False, verify=False) resp_4 = requests.get(virtual_server_setup.backend_2_url_ssl, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False, verify=False) assert resp_3.status_code == 200, "Expected: no redirect for scheme=https" assert resp_4.status_code == 200, "Expected: no redirect for scheme=https"
def test_update(self, kube_apis, crd_ingress_controller, virtual_server_setup): wait_before_test(1) text = f"{virtual_server_setup.namespace}/{virtual_server_setup.vs_name}" vs_event_text = f"Configuration for {text} was added or updated" events_vs = get_events(kube_apis.v1, virtual_server_setup.namespace) initial_count = assert_event_and_get_count(vs_event_text, events_vs) vs_src = f"{TEST_DATA}/virtual-server-redirects/virtual-server-updated.yaml" patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, vs_src, virtual_server_setup.namespace) wait_and_assert_status_code(301, virtual_server_setup.backend_1_url, virtual_server_setup.vs_host, allow_redirects=False) resp = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) assert resp.headers['location'] == "http://demo.nginx.com" wait_and_assert_status_code(302, virtual_server_setup.backend_2_url, virtual_server_setup.vs_host, allow_redirects=False) resp = requests.get(virtual_server_setup.backend_2_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) assert resp.headers['location'] == "http://demo.nginx.com" vs_events = get_events(kube_apis.v1, virtual_server_setup.namespace) assert_event_count_increased(vs_event_text, initial_count, vs_events)
def test_tls_redirect_openapi_validation_flow( self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller, virtual_server_setup): ic_pod_name = get_first_pod_name( kube_apis.v1, ingress_controller_prerequisites.namespace) config_old = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) source_yaml = f"{TEST_DATA}/virtual-server-tls-redirect/virtual-server-invalid.yaml" try: patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, source_yaml, virtual_server_setup.namespace) except ApiException as ex: assert ex.status == 422 \ and "spec.tls.redirect.enable: Invalid value" in ex.body \ and "spec.tls.redirect.code: Invalid value" in ex.body \ and "spec.tls.redirect.basedOn: Invalid value" in ex.body \ and "spec.tls.secret: Invalid value" in ex.body except Exception as ex: pytest.fail(f"An unexpected exception is raised: {ex}") else: pytest.fail("Expected an exception but there was none") wait_before_test(1) config_new = get_vs_nginx_template_conf( kube_apis.v1, virtual_server_setup.namespace, virtual_server_setup.vs_name, ic_pod_name, ingress_controller_prerequisites.namespace) assert config_old == config_new, "Expected: config doesn't change"
def test_deny_policy( self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, config_setup, src, ): """ Test if ip (10.0.0.1) block-listing is working: default(no policy) -> deny """ resp = requests.get( virtual_server_setup.backend_1_url, headers={ "host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1" }, ) print(f"Response: {resp.status_code}\n{resp.text}") assert resp.status_code == 200 print(f"Create deny policy") pol_name = create_policy_from_yaml(kube_apis.custom_objects, deny_pol_src, test_namespace) print(f"Patch vs with policy: {src}") patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, src, virtual_server_setup.namespace, ) wait_before_test() print(f"\nUse IP listed in deny block: 10.0.0.1") resp1 = requests.get( virtual_server_setup.backend_1_url, headers={ "host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1" }, ) print(f"Response: {resp1.status_code}\n{resp1.text}") print(f"\nUse IP not listed in deny block: 10.0.0.2") resp2 = requests.get( virtual_server_setup.backend_1_url, headers={ "host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.2" }, ) print(f"Response: {resp2.status_code}\n{resp2.text}") delete_policy(kube_apis.custom_objects, pol_name, test_namespace) self.restore_default_vs(kube_apis, virtual_server_setup) assert (resp1.status_code == 403 and "403 Forbidden" in resp1.text and resp2.status_code == 200 and "Server address:" in resp2.text)
def test_ingress_mtls_policy_cert( self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, certificate, expected_code, expected_text, exception, ): """ Test ingress-mtls with valid and invalid policy """ session = create_sni_session() mtls_secret, tls_secret, pol_name = setup_policy( kube_apis, test_namespace, mtls_sec_valid_src, tls_sec_valid_src, mtls_pol_valid_src, ) print(f"Patch vs with policy: {mtls_pol_valid_src}") patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, mtls_vs_spec_src, virtual_server_setup.namespace, ) wait_before_test() ssl_exception = "" resp = "" try: resp = session.get( virtual_server_setup.backend_1_url_ssl, cert=certificate, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False, verify=False, ) except requests.exceptions.SSLError as e: print(f"SSL certificate exception: {e}") ssl_exception = str(e) resp = mock.Mock() resp.status_code = "None" resp.text = "None" teardown_policy(kube_apis, test_namespace, tls_secret, pol_name, mtls_secret) patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, std_vs_src, virtual_server_setup.namespace, ) assert (resp.status_code == expected_code and expected_text in resp.text and exception in ssl_exception)
def test_jwt_policy_override_vs_vsr( self, kube_apis, crd_ingress_controller, v_s_route_app_setup, v_s_route_setup, test_namespace, vs_src, ): """ Test if policy specified in vsr:subroute (policy without $httptoken) takes preference over policy specified in: 1. vs:spec (policy with $httptoken) 2. vs:route (policy with $httptoken) """ req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" secret, pol_name_1, pol_name_2, headers = self.setup_multiple_policies( kube_apis, v_s_route_setup.route_m.namespace, valid_token, jwk_sec_valid_src, jwt_pol_valid_src, jwt_pol_multi_src, v_s_route_setup.vs_host, ) print(f"Patch vsr with policies: {jwt_pol_valid_src}") patch_v_s_route_from_yaml( kube_apis.custom_objects, v_s_route_setup.route_m.name, jwt_vsr_valid_multi_src, v_s_route_setup.route_m.namespace, ) patch_virtual_server_from_yaml( kube_apis.custom_objects, v_s_route_setup.vs_name, vs_src, v_s_route_setup.namespace, ) wait_before_test() resp = requests.get(f"{req_url}{v_s_route_setup.route_m.paths[0]}", headers=headers,) print(resp.status_code) delete_policy(kube_apis.custom_objects, pol_name_1, v_s_route_setup.route_m.namespace) delete_policy(kube_apis.custom_objects, pol_name_2, v_s_route_setup.route_m.namespace) delete_secret(kube_apis.v1, secret, v_s_route_setup.route_m.namespace) patch_v_s_route_from_yaml( kube_apis.custom_objects, v_s_route_setup.route_m.name, std_vsr_src, v_s_route_setup.route_m.namespace, ) patch_virtual_server_from_yaml( kube_apis.custom_objects, v_s_route_setup.vs_name, std_vs_src, v_s_route_setup.namespace ) assert resp.status_code == 401 assert f"Authorization Required" in resp.text
def test_deleted_policy(self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, config_setup): """ Test if valid policy is deleted then response is 500 """ resp = requests.get( virtual_server_setup.backend_1_url, headers={ "host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1" }, ) print(f"Response: {resp.status_code}\n{resp.text}") assert resp.status_code == 200 print(f"Create deny policy") patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, deny_vs_src, virtual_server_setup.namespace, ) pol_name = create_policy_from_yaml(kube_apis.custom_objects, deny_pol_src, test_namespace) wait_before_test() vs_info = read_crd( kube_apis.custom_objects, virtual_server_setup.namespace, "virtualservers", virtual_server_setup.vs_name, ) assert vs_info["status"]["state"] == "Valid" delete_policy(kube_apis.custom_objects, pol_name, test_namespace) wait_before_test() resp = requests.get( virtual_server_setup.backend_1_url, headers={ "host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1" }, ) print(f"Response: {resp.status_code}\n{resp.text}") vs_info = read_crd( kube_apis.custom_objects, virtual_server_setup.namespace, "virtualservers", virtual_server_setup.vs_name, ) self.restore_default_vs(kube_apis, virtual_server_setup) assert resp.status_code == 500 and "500 Internal Server Error" in resp.text assert (vs_info["status"]["state"] == "Warning" and vs_info["status"]["reason"] == "UpdatedWithWarning")
def patch_valid_vs(self, kube_apis, v_s_route_setup) -> None: """ Function to revert vs deployment to valid state """ patch_src = f"{TEST_DATA}/virtual-server-route-status/standard/virtual-server.yaml" patch_virtual_server_from_yaml( kube_apis.custom_objects, v_s_route_setup.vs_name, patch_src, v_s_route_setup.namespace, ) wait_before_test()
def test_splits_and_matches(self, kube_apis, crd_ingress_controller, virtual_server_setup, v_s_data): patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-error-pages/{v_s_data['src']}", virtual_server_setup.namespace) wait_and_assert_status_code(v_s_data['expected_code'], virtual_server_setup.backend_1_url, virtual_server_setup.vs_host, allow_redirects=False) resp = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}, allow_redirects=False) assert f'http://{virtual_server_setup.vs_host}/error.html' in resp.next.url
def test_ingress_mtls_policy_vsr( self, kube_apis, crd_ingress_controller, v_s_route_app_setup, v_s_route_setup, test_namespace, ): """ Test ingress-mtls in vsr subroute context. """ mtls_secret, tls_secret, pol_name = setup_policy( kube_apis, v_s_route_setup.route_m.namespace, mtls_sec_valid_src, tls_sec_valid_src, mtls_pol_valid_src, ) print( f"Patch vsr with policy: {mtls_vsr_subroute_src} and vs with tls secret: {tls_secret}" ) patch_virtual_server_from_yaml( kube_apis.custom_objects, v_s_route_setup.vs_name, mtls_vs_vsr_src, v_s_route_setup.namespace, ) patch_v_s_route_from_yaml( kube_apis.custom_objects, v_s_route_setup.route_m.name, mtls_vsr_subroute_src, v_s_route_setup.route_m.namespace, ) wait_before_test() vsr_res = read_vsr( kube_apis.custom_objects, v_s_route_setup.route_m.namespace, v_s_route_setup.route_m.name, ) teardown_policy(kube_apis, v_s_route_setup.route_m.namespace, tls_secret, pol_name, mtls_secret) patch_v_s_route_from_yaml( kube_apis.custom_objects, v_s_route_setup.route_m.name, std_vsr_src, v_s_route_setup.route_m.namespace, ) patch_virtual_server_from_yaml( kube_apis.custom_objects, v_s_route_setup.vs_name, std_vs_vsr_src, v_s_route_setup.namespace, ) assert (vsr_res["status"]["state"] == "Warning" and f"{pol_name} is not allowed in the subroute context" in vsr_res["status"]["message"])
def test_overide_vs_vsr( self, kube_apis, crd_ingress_controller, v_s_route_app_setup, test_namespace, config_setup, v_s_route_setup, src, ): """ Test if vsr subroute policy overrides vs spec policy and vsr subroute policy overrides vs route policy """ req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}" print(f"Create deny policy") deny_pol_name = create_policy_from_yaml( kube_apis.custom_objects, deny_pol_src, v_s_route_setup.route_m.namespace) print(f"Create allow policy") allow_pol_name = create_policy_from_yaml( kube_apis.custom_objects, allow_pol_src, v_s_route_setup.route_m.namespace) patch_v_s_route_from_yaml( kube_apis.custom_objects, v_s_route_setup.route_m.name, allow_vsr_src, v_s_route_setup.route_m.namespace, ) # patch vs with blocking policy patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name, src, v_s_route_setup.namespace) wait_before_test() print(f"\nUse IP listed in deny block: 10.0.0.1") resp = requests.get( f"{req_url}{v_s_route_setup.route_m.paths[0]}", headers={ "host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1" }, ) print(f"Response: {resp.status_code}\n{resp.text}") delete_policy(kube_apis.custom_objects, deny_pol_name, v_s_route_setup.route_m.namespace) delete_policy(kube_apis.custom_objects, allow_pol_name, v_s_route_setup.route_m.namespace) self.restore_default_vsr(kube_apis, v_s_route_setup) patch_virtual_server_from_yaml(kube_apis.custom_objects, v_s_route_setup.vs_name, std_vs_src, v_s_route_setup.namespace) wait_before_test() assert resp.status_code == 200 and "Server address:" in resp.text
def test_ingress_mtls_policy( self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, policy_src, vs_src, expected_code, expected_text, vs_message, vs_state, ): """ Test ingress-mtls with valid and invalid policy in vs spec and route contexts. """ session = create_sni_session() mtls_secret, tls_secret, pol_name = setup_policy( kube_apis, test_namespace, mtls_sec_valid_src, tls_sec_valid_src, policy_src, ) print(f"Patch vs with policy: {policy_src}") patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, vs_src, virtual_server_setup.namespace, ) wait_before_test() resp = session.get( virtual_server_setup.backend_1_url_ssl, cert=(crt, key), headers={"host": virtual_server_setup.vs_host}, allow_redirects=False, verify=False, ) vs_res = read_vs(kube_apis.custom_objects, test_namespace, virtual_server_setup.vs_name) teardown_policy(kube_apis, test_namespace, tls_secret, pol_name, mtls_secret) patch_virtual_server_from_yaml( kube_apis.custom_objects, virtual_server_setup.vs_name, std_vs_src, virtual_server_setup.namespace, ) assert (resp.status_code == expected_code and expected_text in resp.text and vs_message in vs_res["status"]["message"] and vs_res["status"]["state"] == vs_state)
def test_flow_with_variable(self, kube_apis, crd_ingress_controller, virtual_server_setup): patch_virtual_server_from_yaml(kube_apis.custom_objects, virtual_server_setup.vs_name, f"{TEST_DATA}/virtual-server-advanced-routing/virtual-server-variable.yaml", virtual_server_setup.namespace) wait_before_test(1) resp_1 = requests.get(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_2 = requests.post(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) resp_3 = requests.put(virtual_server_setup.backend_1_url, headers={"host": virtual_server_setup.vs_host}) execute_assertions(resp_1, resp_2, resp_3)