github.com/nginxinc/kubernetes-ingress@v1.12.5/tests/suite/test_ingress_mtls.py (about) 1 import mock 2 import pytest 3 import requests 4 from suite.resources_utils import ( 5 wait_before_test, 6 create_secret_from_yaml, 7 delete_secret, 8 ) 9 from suite.ssl_utils import create_sni_session 10 from suite.custom_resources_utils import ( 11 read_vs, 12 read_vsr, 13 patch_virtual_server_from_yaml, 14 create_policy_from_yaml, 15 delete_policy, 16 patch_v_s_route_from_yaml, 17 ) 18 from settings import TEST_DATA 19 20 std_vs_src = f"{TEST_DATA}/virtual-server/standard/virtual-server.yaml" 21 std_vsr_src = f"{TEST_DATA}/virtual-server-route/route-multiple.yaml" 22 std_vs_vsr_src = f"{TEST_DATA}/virtual-server-route/standard/virtual-server.yaml" 23 24 mtls_sec_valid_src = f"{TEST_DATA}/ingress-mtls/secret/ingress-mtls-secret.yaml" 25 tls_sec_valid_src = f"{TEST_DATA}/ingress-mtls/secret/tls-secret.yaml" 26 27 mtls_pol_valid_src = f"{TEST_DATA}/ingress-mtls/policies/ingress-mtls.yaml" 28 mtls_pol_invalid_src = f"{TEST_DATA}/ingress-mtls/policies/ingress-mtls-invalid.yaml" 29 30 mtls_vs_spec_src = f"{TEST_DATA}/ingress-mtls/spec/virtual-server-mtls.yaml" 31 mtls_vs_route_src = f"{TEST_DATA}/ingress-mtls/route-subroute/virtual-server-mtls.yaml" 32 mtls_vsr_subroute_src = f"{TEST_DATA}/ingress-mtls/route-subroute/virtual-server-route-mtls.yaml" 33 mtls_vs_vsr_src = f"{TEST_DATA}/ingress-mtls/route-subroute/virtual-server-vsr.yaml" 34 35 crt = f"{TEST_DATA}/ingress-mtls/client-auth/valid/client-cert.pem" 36 key = f"{TEST_DATA}/ingress-mtls/client-auth/valid/client-key.pem" 37 invalid_crt = f"{TEST_DATA}/ingress-mtls/client-auth/invalid/client-cert.pem" 38 invalid_key = f"{TEST_DATA}/ingress-mtls/client-auth/invalid/client-cert.pem" 39 40 41 def setup_policy(kube_apis, test_namespace, mtls_secret, tls_secret, policy): 42 print(f"Create ingress-mtls secret") 43 mtls_secret_name = create_secret_from_yaml(kube_apis.v1, test_namespace, mtls_secret) 44 45 print(f"Create ingress-mtls policy") 46 pol_name = create_policy_from_yaml(kube_apis.custom_objects, policy, test_namespace) 47 48 print(f"Create tls secret") 49 tls_secret_name = create_secret_from_yaml(kube_apis.v1, test_namespace, tls_secret) 50 return mtls_secret_name, tls_secret_name, pol_name 51 52 53 def teardown_policy(kube_apis, test_namespace, tls_secret, pol_name, mtls_secret): 54 55 print("Delete policy and related secrets") 56 delete_secret(kube_apis.v1, tls_secret, test_namespace) 57 delete_policy(kube_apis.custom_objects, pol_name, test_namespace) 58 delete_secret(kube_apis.v1, mtls_secret, test_namespace) 59 60 61 @pytest.mark.policies 62 @pytest.mark.parametrize( 63 "crd_ingress_controller, virtual_server_setup", 64 [ 65 ( 66 { 67 "type": "complete", 68 "extra_args": [ 69 f"-enable-leader-election=false", 70 f"-enable-preview-policies", 71 ], 72 }, 73 { 74 "example": "virtual-server", 75 "app_type": "simple", 76 }, 77 ) 78 ], 79 indirect=True, 80 ) 81 class TestIngressMtlsPolicyVS: 82 @pytest.mark.parametrize( 83 "policy_src, vs_src, expected_code, expected_text, vs_message, vs_state", 84 [ 85 ( 86 mtls_pol_valid_src, 87 mtls_vs_spec_src, 88 200, 89 "Server address:", 90 "was added or updated", 91 "Valid", 92 ), 93 ( 94 mtls_pol_valid_src, 95 mtls_vs_route_src, 96 500, 97 "Internal Server Error", 98 "is not allowed in the route context", 99 "Warning", 100 ), 101 ( 102 mtls_pol_invalid_src, 103 mtls_vs_spec_src, 104 500, 105 "Internal Server Error", 106 "is missing or invalid", 107 "Warning", 108 ), 109 ], 110 ) 111 @pytest.mark.smoke 112 def test_ingress_mtls_policy( 113 self, 114 kube_apis, 115 crd_ingress_controller, 116 virtual_server_setup, 117 test_namespace, 118 policy_src, 119 vs_src, 120 expected_code, 121 expected_text, 122 vs_message, 123 vs_state, 124 ): 125 """ 126 Test ingress-mtls with valid and invalid policy in vs spec and route contexts. 127 """ 128 session = create_sni_session() 129 mtls_secret, tls_secret, pol_name = setup_policy( 130 kube_apis, 131 test_namespace, 132 mtls_sec_valid_src, 133 tls_sec_valid_src, 134 policy_src, 135 ) 136 137 print(f"Patch vs with policy: {policy_src}") 138 patch_virtual_server_from_yaml( 139 kube_apis.custom_objects, 140 virtual_server_setup.vs_name, 141 vs_src, 142 virtual_server_setup.namespace, 143 ) 144 wait_before_test() 145 resp = session.get( 146 virtual_server_setup.backend_1_url_ssl, 147 cert=(crt, key), 148 headers={"host": virtual_server_setup.vs_host}, 149 allow_redirects=False, 150 verify=False, 151 ) 152 vs_res = read_vs(kube_apis.custom_objects, test_namespace, virtual_server_setup.vs_name) 153 teardown_policy(kube_apis, test_namespace, tls_secret, pol_name, mtls_secret) 154 155 patch_virtual_server_from_yaml( 156 kube_apis.custom_objects, 157 virtual_server_setup.vs_name, 158 std_vs_src, 159 virtual_server_setup.namespace, 160 ) 161 assert ( 162 resp.status_code == expected_code 163 and expected_text in resp.text 164 and vs_message in vs_res["status"]["message"] 165 and vs_res["status"]["state"] == vs_state 166 ) 167 168 @pytest.mark.parametrize( 169 "certificate, expected_code, expected_text, exception", 170 [ 171 ((crt, key), 200, "Server address:", ""), 172 ("", 400, "No required SSL certificate was sent", ""), 173 ((invalid_crt, invalid_key), "None", "None", "Caused by SSLError"), 174 ], 175 ) 176 def test_ingress_mtls_policy_cert( 177 self, 178 kube_apis, 179 crd_ingress_controller, 180 virtual_server_setup, 181 test_namespace, 182 certificate, 183 expected_code, 184 expected_text, 185 exception, 186 ): 187 """ 188 Test ingress-mtls with valid and invalid policy 189 """ 190 session = create_sni_session() 191 mtls_secret, tls_secret, pol_name = setup_policy( 192 kube_apis, 193 test_namespace, 194 mtls_sec_valid_src, 195 tls_sec_valid_src, 196 mtls_pol_valid_src, 197 ) 198 199 print(f"Patch vs with policy: {mtls_pol_valid_src}") 200 patch_virtual_server_from_yaml( 201 kube_apis.custom_objects, 202 virtual_server_setup.vs_name, 203 mtls_vs_spec_src, 204 virtual_server_setup.namespace, 205 ) 206 wait_before_test() 207 ssl_exception = "" 208 resp = "" 209 try: 210 resp = session.get( 211 virtual_server_setup.backend_1_url_ssl, 212 cert=certificate, 213 headers={"host": virtual_server_setup.vs_host}, 214 allow_redirects=False, 215 verify=False, 216 ) 217 except requests.exceptions.SSLError as e: 218 print(f"SSL certificate exception: {e}") 219 ssl_exception = str(e) 220 resp = mock.Mock() 221 resp.status_code = "None" 222 resp.text = "None" 223 224 teardown_policy(kube_apis, test_namespace, tls_secret, pol_name, mtls_secret) 225 226 patch_virtual_server_from_yaml( 227 kube_apis.custom_objects, 228 virtual_server_setup.vs_name, 229 std_vs_src, 230 virtual_server_setup.namespace, 231 ) 232 assert ( 233 resp.status_code == expected_code 234 and expected_text in resp.text 235 and exception in ssl_exception 236 ) 237 238 @pytest.mark.policies 239 @pytest.mark.parametrize( 240 "crd_ingress_controller, v_s_route_setup", 241 [ 242 ( 243 { 244 "type": "complete", 245 "extra_args": [ 246 f"-enable-leader-election=false", 247 f"-enable-preview-policies", 248 ], 249 }, 250 {"example": "virtual-server-route"}, 251 ) 252 ], 253 indirect=True, 254 ) 255 class TestIngressMtlsPolicyVSR: 256 def test_ingress_mtls_policy_vsr( 257 self, 258 kube_apis, 259 crd_ingress_controller, 260 v_s_route_app_setup, 261 v_s_route_setup, 262 test_namespace, 263 ): 264 """ 265 Test ingress-mtls in vsr subroute context. 266 """ 267 mtls_secret, tls_secret, pol_name = setup_policy( 268 kube_apis, 269 v_s_route_setup.route_m.namespace, 270 mtls_sec_valid_src, 271 tls_sec_valid_src, 272 mtls_pol_valid_src, 273 ) 274 print( 275 f"Patch vsr with policy: {mtls_vsr_subroute_src} and vs with tls secret: {tls_secret}" 276 ) 277 patch_virtual_server_from_yaml( 278 kube_apis.custom_objects, 279 v_s_route_setup.vs_name, 280 mtls_vs_vsr_src, 281 v_s_route_setup.namespace, 282 ) 283 patch_v_s_route_from_yaml( 284 kube_apis.custom_objects, 285 v_s_route_setup.route_m.name, 286 mtls_vsr_subroute_src, 287 v_s_route_setup.route_m.namespace, 288 ) 289 wait_before_test() 290 vsr_res = read_vsr( 291 kube_apis.custom_objects, 292 v_s_route_setup.route_m.namespace, 293 v_s_route_setup.route_m.name, 294 ) 295 teardown_policy( 296 kube_apis, v_s_route_setup.route_m.namespace, tls_secret, pol_name, mtls_secret 297 ) 298 patch_v_s_route_from_yaml( 299 kube_apis.custom_objects, 300 v_s_route_setup.route_m.name, 301 std_vsr_src, 302 v_s_route_setup.route_m.namespace, 303 ) 304 patch_virtual_server_from_yaml( 305 kube_apis.custom_objects, 306 v_s_route_setup.vs_name, 307 std_vs_vsr_src, 308 v_s_route_setup.namespace, 309 ) 310 assert ( 311 vsr_res["status"]["state"] == "Warning" 312 and f"{pol_name} is not allowed in the subroute context" in vsr_res["status"]["message"] 313 )