def test_ic_template_config_upstream_rule(self, kube_apis, ingress_controller_prerequisites, ingress_controller, external_name_setup): result_conf = get_ingress_nginx_template_conf(kube_apis.v1, external_name_setup.namespace, external_name_setup.ingress_name, external_name_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) assert "random two least_conn;" in result_conf
def test_when_annotation_in_ing_only(self, kube_apis, annotations_setup, ingress_controller_prerequisites, annotations, expected_strings, unexpected_strings): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) initial_count = get_event_count(annotations_setup.ingress_event_text, initial_events) print("Case 2: no ConfigMap keys, annotations in Ingress only") new_ing = generate_ingresses_with_annotation( annotations_setup.ingress_src_file, annotations) for ing in new_ing: # in mergeable case this will update master ingress only if ing['metadata']['name'] == annotations_setup.ingress_name: replace_ingress(kube_apis.networking_v1, annotations_setup.ingress_name, annotations_setup.namespace, ing) wait_before_test(1) result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert_event_count_increased(annotations_setup.ingress_event_text, initial_count, new_events) for _ in expected_strings: assert _ in result_conf for _ in unexpected_strings: assert _ not in result_conf
def test_validation(self, kube_apis, annotations_setup, ingress_controller_prerequisites, annotations): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) print("Case 6: IC doesn't validate, only nginx validates") initial_count = get_event_count( annotations_setup.ingress_error_event_text, initial_events) new_ing = generate_ingresses_with_annotation( annotations_setup.ingress_src_file, annotations) for ing in new_ing: # in mergeable case this will update master ingress only if ing['metadata']['name'] == annotations_setup.ingress_name: replace_ingress(kube_apis.networking_v1, annotations_setup.ingress_name, annotations_setup.namespace, ing) wait_before_test() result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert "server {" not in result_conf assert "No such file or directory" in result_conf assert_event_count_increased( annotations_setup.ingress_error_event_text, initial_count, new_events)
def test_when_annotation_in_configmap_only( self, kube_apis, annotations_setup, ingress_controller_prerequisites, configmap_file, expected_strings, unexpected_strings): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) initial_count = get_event_count(annotations_setup.ingress_event_text, initial_events) print("Case 3: keys in ConfigMap, no annotations in Ingress") replace_ingresses_from_yaml(kube_apis.extensions_v1_beta1, annotations_setup.namespace, annotations_setup.ingress_src_file) replace_configmap_from_yaml( kube_apis.v1, ingress_controller_prerequisites.config_map['metadata']['name'], ingress_controller_prerequisites.namespace, configmap_file) wait_before_test(1) result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert_event_count_increased(annotations_setup.ingress_event_text, initial_count, new_events) for _ in expected_strings: assert _ in result_conf for _ in unexpected_strings: assert _ not in result_conf
def test_ap_nginx_config_entries(self, kube_apis, crd_ingress_controller_with_ap, appprotect_setup, test_namespace): """ Test to verify AppProtect annotations in nginx config """ conf_annotations = [ f"app_protect_enable on;", f"app_protect_policy_file /etc/nginx/waf/nac-policies/{test_namespace}_{ap_policy};", f"app_protect_security_log_enable on;", f"app_protect_security_log /etc/nginx/waf/nac-logconfs/{test_namespace}_logconf syslog:server=127.0.0.1:514;", ] create_ingress_with_ap_annotations(kube_apis, src_ing_yaml, test_namespace, ap_policy, "True", "True", "127.0.0.1:514") wait_before_test(40) pod_name = get_first_pod_name(kube_apis.v1, "nginx-ingress") result_conf = get_ingress_nginx_template_conf(kube_apis.v1, test_namespace, "appprotect-ingress", pod_name, "nginx-ingress") delete_items_from_yaml(kube_apis, src_ing_yaml, test_namespace) for _ in conf_annotations: assert _ in result_conf
def test_ing_overrides_configmap(self, kube_apis, annotations_setup, ingress_controller_prerequisites, annotations, configmap_file, expected_strings, unexpected_strings): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) initial_count = get_event_count(annotations_setup.ingress_event_text, initial_events) print("Case 4: keys in ConfigMap, annotations in Ingress") new_ing = generate_ingresses_with_annotation( annotations_setup.ingress_src_file, annotations) for ing in new_ing: # in mergeable case this will update master ingress only if ing['metadata']['name'] == annotations_setup.ingress_name: replace_ingress(kube_apis.extensions_v1_beta1, annotations_setup.ingress_name, annotations_setup.namespace, ing) replace_configmap_from_yaml( kube_apis.v1, ingress_controller_prerequisites.config_map['metadata']['name'], ingress_controller_prerequisites.namespace, configmap_file) wait_before_test(1) result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert_event_count_increased(annotations_setup.ingress_event_text, initial_count, new_events) for _ in expected_strings: assert _ in result_conf for _ in unexpected_strings: assert _ not in result_conf
def test_validation(self, kube_apis, annotations_setup, ingress_controller_prerequisites, annotations, expected_strings, unexpected_strings): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) print("Case 6: IC doesn't validate, only nginx validates") initial_count = get_event_count( annotations_setup.ingress_error_event_text, initial_events) new_ing = generate_ingresses_with_annotation( annotations_setup.ingress_src_file, annotations) for ing in new_ing: # in mergeable case this will update master ingress only if ing['metadata']['name'] == annotations_setup.ingress_name: replace_ingress(kube_apis.extensions_v1_beta1, annotations_setup.ingress_name, annotations_setup.namespace, ing) wait_before_test(1) result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert_event_count_increased( annotations_setup.ingress_error_event_text, initial_count, new_events) for _ in expected_strings: assert _ in result_conf for _ in unexpected_strings: assert _ not in result_conf
def test_ic_template_config_upstream_server(self, kube_apis, ingress_controller_prerequisites, ingress_controller, ingress_controller_endpoint, external_name_setup): result_conf = get_ingress_nginx_template_conf(kube_apis.v1, external_name_setup.namespace, external_name_setup.ingress_name, external_name_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) assert f"server {external_name_setup.external_host}:80 max_fails=1 fail_timeout=10s resolve;" in result_conf
def test_upstream_zone_size_0(self, cli_arguments, kube_apis, annotations_setup, ingress_controller_prerequisites, annotations): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) initial_count = get_event_count(annotations_setup.ingress_event_text, initial_events) print("Edge Case: upstream-zone-size is 0") new_ing = generate_ingresses_with_annotation( annotations_setup.ingress_src_file, annotations) for ing in new_ing: # in mergeable case this will update master ingress only if ing['metadata']['name'] == annotations_setup.ingress_name: replace_ingress(kube_apis.extensions_v1_beta1, annotations_setup.ingress_name, annotations_setup.namespace, ing) wait_before_test(1) result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert_event_count_increased(annotations_setup.ingress_event_text, initial_count, new_events) if cli_arguments["ic-type"] == "nginx-plus-ingress": print("Run assertions for Nginx Plus case") assert "zone " in result_conf assert " 256k;" in result_conf elif cli_arguments["ic-type"] == "nginx-ingress": print("Run assertions for Nginx OSS case") assert "zone " not in result_conf assert " 256k;" not in result_conf
def test_grpc_flow(self, kube_apis, annotations_grpc_setup, ingress_controller_prerequisites, annotations, expected_strings, unexpected_strings): initial_events = get_events(kube_apis.v1, annotations_grpc_setup.namespace) initial_count = get_event_count( annotations_grpc_setup.ingress_event_text, initial_events) print("Case 5: grpc annotations override http ones") new_ing = generate_ingresses_with_annotation( annotations_grpc_setup.ingress_src_file, annotations) for ing in new_ing: if ing['metadata']['name'] == annotations_grpc_setup.ingress_name: replace_ingress(kube_apis.extensions_v1_beta1, annotations_grpc_setup.ingress_name, annotations_grpc_setup.namespace, ing) wait_before_test(1) result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_grpc_setup.namespace, annotations_grpc_setup.ingress_name, annotations_grpc_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_grpc_setup.namespace) assert_event_count_increased(annotations_grpc_setup.ingress_event_text, initial_count, new_events) for _ in expected_strings: assert _ in result_conf for _ in unexpected_strings: assert _ not in result_conf
def test_ic_template_config_upstream_zone(self, kube_apis, ingress_controller_prerequisites, ingress_controller, external_name_setup): result_conf = get_ingress_nginx_template_conf(kube_apis.v1, external_name_setup.namespace, external_name_setup.ingress_name, external_name_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) line = f"zone {external_name_setup.namespace}-{external_name_setup.ingress_name}-{external_name_setup.ingress_host}-{external_name_setup.service}-80 256k;" assert line in result_conf
def test_nginx_config_defaults(self, kube_apis, annotations_setup, ingress_controller_prerequisites): print("Case 1: no ConfigMap keys, no annotations in Ingress") result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) assert "proxy_send_timeout 60s;" in result_conf
def test_nginx_config(self, kube_apis, ingress_controller_prerequisites, ingress_controller, custom_annotations_setup, expected_texts): result_conf = get_ingress_nginx_template_conf( kube_apis.v1, custom_annotations_setup.namespace, custom_annotations_setup.ingress_name, custom_annotations_setup.ic_pod_name, ingress_controller_prerequisites.namespace) for line in expected_texts: assert line in result_conf
def test_nginx_config_defaults(self, kube_apis, annotations_setup, ingress_controller_prerequisites): print("Case 1: no ConfigMap keys, no annotations in Ingress") result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) assert "proxy_send_timeout 60s;" in result_conf assert "max_conns=0;" in result_conf assert "Strict-Transport-Security" not in result_conf for upstream in annotations_setup.upstream_names: assert f"zone {upstream} 256k;" in result_conf
def test_minion_overrides_master(self, kube_apis, annotations_setup, ingress_controller_prerequisites, yaml_file, expected_strings, unexpected_strings): initial_events = get_events(kube_apis.v1, annotations_setup.namespace) initial_count = get_event_count(annotations_setup.ingress_event_text, initial_events) print("Case 7: minion annotation overrides master") replace_ingresses_from_yaml(kube_apis.extensions_v1_beta1, annotations_setup.namespace, yaml_file) wait_before_test(1) result_conf = get_ingress_nginx_template_conf(kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) new_events = get_events(kube_apis.v1, annotations_setup.namespace) assert_event_count_increased(annotations_setup.ingress_event_text, initial_count, new_events) for _ in expected_strings: assert _ in result_conf for _ in unexpected_strings: assert _ not in result_conf
def test_ap_nginx_config_entries(self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller_with_dos, dos_setup, test_namespace): """ Test to verify Dos directive in nginx config """ conf_directive = [ f"app_protect_dos_enable on;", f"app_protect_dos_security_log_enable on;", f"app_protect_dos_monitor uri=dos.example.com protocol=http1 timeout=5;", f"app_protect_dos_name \"{test_namespace}/dos-protected/name\";", f"app_protect_dos_policy_file /etc/nginx/dos/policies/{test_namespace}_{dos_setup.pol_name}.json;", f"app_protect_dos_security_log_enable on;", f"app_protect_dos_security_log /etc/nginx/dos/logconfs/{test_namespace}_{dos_setup.log_name}.json syslog:server=syslog-svc.{ingress_controller_prerequisites.namespace}.svc.cluster.local:514;", ] create_ingress_with_dos_annotations( kube_apis, src_ing_yaml, test_namespace, test_namespace + "/dos-protected", ) ingress_host = get_first_ingress_host_from_yaml(src_ing_yaml) ensure_response_from_backend(dos_setup.req_url, ingress_host, check404=True) pod_name = self.getPodNameThatContains( kube_apis, ingress_controller_prerequisites.namespace, "nginx-ingress") result_conf = get_ingress_nginx_template_conf(kube_apis.v1, test_namespace, "dos-ingress", pod_name, "nginx-ingress") delete_items_from_yaml(kube_apis, src_ing_yaml, test_namespace) for _ in conf_directive: assert _ in result_conf
def test_nginx_config_defaults(self, kube_apis, annotations_setup, ingress_controller_prerequisites, cli_arguments): print("Case 1: no ConfigMap keys, no annotations in Ingress") result_conf = get_ingress_nginx_template_conf( kube_apis.v1, annotations_setup.namespace, annotations_setup.ingress_name, annotations_setup.ingress_pod_name, ingress_controller_prerequisites.namespace) assert "proxy_send_timeout 60s;" in result_conf assert "max_conns=0;" in result_conf assert "Strict-Transport-Security" not in result_conf expected_zone_size = "256k" if cli_arguments["ic-type"] == "nginx-plus-ingress": expected_zone_size = "512k" for upstream in annotations_setup.upstream_names: assert f"zone {upstream} {expected_zone_size};" in result_conf
def test_dos_sec_logs_on( self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller_with_dos, dos_setup, test_namespace, ): """ Test corresponding log entries with correct policy (includes setting up a syslog server as defined in syslog.yaml) """ print( "----------------------- Get syslog pod name ----------------------" ) syslog_pod = self.getPodNameThatContains( kube_apis, ingress_controller_prerequisites.namespace, "syslog") assert "syslog" in syslog_pod log_loc = f"/var/log/messages" clear_file_contents(kube_apis.v1, log_loc, syslog_pod, ingress_controller_prerequisites.namespace) create_ingress_with_dos_annotations(kube_apis, src_ing_yaml, test_namespace, test_namespace + "/dos-protected") ingress_host = get_first_ingress_host_from_yaml(src_ing_yaml) print( "--------- Run test while DOS module is enabled with correct policy ---------" ) ensure_response_from_backend(dos_setup.req_url, ingress_host, check404=True) pod_name = self.getPodNameThatContains( kube_apis, ingress_controller_prerequisites.namespace, "nginx-ingress") get_ingress_nginx_template_conf(kube_apis.v1, test_namespace, "dos-ingress", pod_name, "nginx-ingress") print("----------------------- Send request ----------------------") response = requests.get(dos_setup.req_url, headers={"host": "dos.example.com"}, verify=False) print(response.text) wait_before_test(10) print( f'log_loc {log_loc} syslog_pod {syslog_pod} namespace {ingress_controller_prerequisites.namespace}' ) log_contents = get_file_contents( kube_apis.v1, log_loc, syslog_pod, ingress_controller_prerequisites.namespace) delete_items_from_yaml(kube_apis, src_ing_yaml, test_namespace) print(log_contents) assert 'product="app-protect-dos"' in log_contents assert f'vs_name="{test_namespace}/dos-protected/name"' in log_contents assert 'bad_actor' in log_contents