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

     1  import pytest, requests
     2  from kubernetes.client.rest import ApiException
     3  from suite.resources_utils import wait_before_test, replace_configmap_from_yaml
     4  from suite.custom_resources_utils import (
     5      read_custom_resource,
     6      delete_virtual_server,
     7      create_virtual_server_from_yaml,
     8      patch_virtual_server_from_yaml,
     9      patch_v_s_route_from_yaml,
    10      create_policy_from_yaml,
    11      delete_policy,
    12  )
    13  from settings import TEST_DATA, DEPLOYMENTS
    14  
    15  std_cm_src = f"{DEPLOYMENTS}/common/nginx-config.yaml"
    16  test_cm_src = f"{TEST_DATA}/access-control/configmap/nginx-config.yaml"
    17  std_vs_src = f"{TEST_DATA}/virtual-server-route/standard/virtual-server.yaml"
    18  deny_pol_src = f"{TEST_DATA}/access-control/policies/access-control-policy-deny.yaml"
    19  allow_pol_src = f"{TEST_DATA}/access-control/policies/access-control-policy-allow.yaml"
    20  invalid_pol_src = f"{TEST_DATA}/access-control/policies/access-control-policy-invalid.yaml"
    21  deny_vsr_src = f"{TEST_DATA}/access-control/route-subroute/virtual-server-route-deny-subroute.yaml"
    22  allow_vsr_src = (
    23      f"{TEST_DATA}/access-control/route-subroute/virtual-server-route-allow-subroute.yaml"
    24  )
    25  override_vsr_src = (
    26      f"{TEST_DATA}/access-control/route-subroute/virtual-server-route-override-subroute.yaml"
    27  )
    28  invalid_vsr_src = (
    29      f"{TEST_DATA}/access-control/route-subroute/virtual-server-route-invalid-subroute.yaml"
    30  )
    31  vs_spec_vsr_override_src = (
    32      f"{TEST_DATA}/access-control/route-subroute/virtual-server-vsr-spec-override.yaml"
    33  )
    34  vs_route_vsr_override_src = (
    35      f"{TEST_DATA}/access-control/route-subroute/virtual-server-vsr-route-override.yaml"
    36  )
    37  
    38  
    39  @pytest.fixture(scope="class")
    40  def config_setup(request, kube_apis, ingress_controller_prerequisites) -> None:
    41      """
    42      Replace configmap to add "set-real-ip-from"
    43      :param request: pytest fixture
    44      :param kube_apis: client apis
    45      :param ingress_controller_prerequisites: IC pre-requisites
    46      """
    47      print(f"------------- Replace ConfigMap --------------")
    48      replace_configmap_from_yaml(
    49          kube_apis.v1,
    50          ingress_controller_prerequisites.config_map["metadata"]["name"],
    51          ingress_controller_prerequisites.namespace,
    52          test_cm_src,
    53      )
    54  
    55      def fin():
    56          print(f"------------- Restore ConfigMap --------------")
    57          replace_configmap_from_yaml(
    58              kube_apis.v1,
    59              ingress_controller_prerequisites.config_map["metadata"]["name"],
    60              ingress_controller_prerequisites.namespace,
    61              std_cm_src,
    62          )
    63  
    64      request.addfinalizer(fin)
    65  
    66  
    67  @pytest.mark.policies
    68  @pytest.mark.parametrize(
    69      "crd_ingress_controller, v_s_route_setup",
    70      [
    71          (
    72              {
    73                  "type": "complete",
    74                  "extra_args": [f"-enable-custom-resources", f"-enable-leader-election=false"],
    75              },
    76              {"example": "virtual-server-route"},
    77          )
    78      ],
    79      indirect=True,
    80  )
    81  class TestAccessControlPoliciesVsr:
    82      def restore_default_vsr(self, kube_apis, v_s_route_setup) -> None:
    83          """
    84          Function to revert vsr deployments to valid state
    85          """
    86          patch_src_m = f"{TEST_DATA}/virtual-server-route/route-multiple.yaml"
    87          patch_v_s_route_from_yaml(
    88              kube_apis.custom_objects,
    89              v_s_route_setup.route_m.name,
    90              patch_src_m,
    91              v_s_route_setup.route_m.namespace,
    92          )
    93          wait_before_test()
    94  
    95      def test_deny_policy_vsr(
    96          self,
    97          kube_apis,
    98          crd_ingress_controller,
    99          v_s_route_app_setup,
   100          test_namespace,
   101          config_setup,
   102          v_s_route_setup,
   103      ):
   104          """
   105          Test if ip (10.0.0.1) block-listing is working (policy specified in vsr subroute): default(no policy) -> deny
   106          """
   107          req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}"
   108          resp = requests.get(
   109              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   110              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   111          )
   112          print(f"Response: {resp.status_code}\n{resp.text}")
   113          assert resp.status_code == 200
   114  
   115          print(f"Create deny policy")
   116          pol_name = create_policy_from_yaml(
   117              kube_apis.custom_objects, deny_pol_src, v_s_route_setup.route_m.namespace
   118          )
   119          patch_v_s_route_from_yaml(
   120              kube_apis.custom_objects,
   121              v_s_route_setup.route_m.name,
   122              deny_vsr_src,
   123              v_s_route_setup.route_m.namespace,
   124          )
   125          wait_before_test()
   126          policy_info = read_custom_resource(
   127              kube_apis.custom_objects, v_s_route_setup.route_m.namespace, "policies", pol_name
   128          )
   129  
   130          print(f"\nUse IP listed in deny block: 10.0.0.1")
   131          resp1 = requests.get(
   132              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   133              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   134          )
   135          print(f"Response: {resp1.status_code}\n{resp1.text}")
   136          print(f"\nUse IP not listed in deny block: 10.0.0.2")
   137          resp2 = requests.get(
   138              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   139              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.2"},
   140          )
   141          print(f"Response: {resp2.status_code}\n{resp2.text}")
   142  
   143          delete_policy(kube_apis.custom_objects, pol_name, v_s_route_setup.route_m.namespace)
   144          self.restore_default_vsr(kube_apis, v_s_route_setup)
   145          assert (
   146              policy_info["status"]
   147              and policy_info["status"]["reason"] == "AddedOrUpdated"
   148              and policy_info["status"]["state"] == "Valid"
   149          )
   150          assert (
   151              resp1.status_code == 403
   152              and "403 Forbidden" in resp1.text
   153              and resp2.status_code == 200
   154              and "Server address:" in resp2.text
   155          )
   156  
   157      def test_allow_policy_vsr(
   158          self,
   159          kube_apis,
   160          crd_ingress_controller,
   161          v_s_route_app_setup,
   162          test_namespace,
   163          config_setup,
   164          v_s_route_setup,
   165      ):
   166          """
   167          Test if ip (10.0.0.1) block-listing is working (policy specified in vsr subroute): default(no policy) -> deny
   168          """
   169          req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}"
   170          resp = requests.get(
   171              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   172              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   173          )
   174          print(f"Response: {resp.status_code}\n{resp.text}")
   175          assert resp.status_code == 200
   176  
   177          print(f"Create allow policy")
   178          pol_name = create_policy_from_yaml(
   179              kube_apis.custom_objects, allow_pol_src, v_s_route_setup.route_m.namespace
   180          )
   181          patch_v_s_route_from_yaml(
   182              kube_apis.custom_objects,
   183              v_s_route_setup.route_m.name,
   184              allow_vsr_src,
   185              v_s_route_setup.route_m.namespace,
   186          )
   187          wait_before_test()
   188          policy_info = read_custom_resource(
   189              kube_apis.custom_objects, v_s_route_setup.route_m.namespace, "policies", pol_name
   190          )
   191  
   192          print(f"\nUse IP listed in deny block: 10.0.0.1")
   193          resp1 = requests.get(
   194              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   195              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   196          )
   197          print(f"Response: {resp1.status_code}\n{resp1.text}")
   198          print(f"\nUse IP not listed in deny block: 10.0.0.2")
   199          resp2 = requests.get(
   200              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   201              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.2"},
   202          )
   203          print(f"Response: {resp2.status_code}\n{resp2.text}")
   204  
   205          delete_policy(kube_apis.custom_objects, pol_name, v_s_route_setup.route_m.namespace)
   206          self.restore_default_vsr(kube_apis, v_s_route_setup)
   207          assert (
   208              policy_info["status"]
   209              and policy_info["status"]["reason"] == "AddedOrUpdated"
   210              and policy_info["status"]["state"] == "Valid"
   211          )
   212          assert (
   213              resp2.status_code == 403
   214              and "403 Forbidden" in resp2.text
   215              and resp1.status_code == 200
   216              and "Server address:" in resp1.text
   217          )
   218  
   219      def test_override_policy_vsr(
   220          self,
   221          kube_apis,
   222          crd_ingress_controller,
   223          v_s_route_app_setup,
   224          test_namespace,
   225          config_setup,
   226          v_s_route_setup,
   227      ):
   228          """
   229          Test if ip (10.0.0.1) allow-listing overrides block-listing (policy specified in vsr subroute)
   230          """
   231          req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}"
   232          resp = requests.get(
   233              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   234              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   235          )
   236          print(f"Response: {resp.status_code}\n{resp.text}")
   237          assert resp.status_code == 200
   238  
   239          print(f"Create deny policy")
   240          deny_pol_name = create_policy_from_yaml(
   241              kube_apis.custom_objects, deny_pol_src, v_s_route_setup.route_m.namespace
   242          )
   243          print(f"Create allow policy")
   244          allow_pol_name = create_policy_from_yaml(
   245              kube_apis.custom_objects, allow_pol_src, v_s_route_setup.route_m.namespace
   246          )
   247          patch_v_s_route_from_yaml(
   248              kube_apis.custom_objects,
   249              v_s_route_setup.route_m.name,
   250              override_vsr_src,
   251              v_s_route_setup.route_m.namespace,
   252          )
   253          wait_before_test()
   254  
   255          print(f"\nUse IP listed in deny block: 10.0.0.1")
   256          resp1 = requests.get(
   257              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   258              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   259          )
   260          print(f"Response: {resp1.status_code}\n{resp1.text}")
   261          print(f"\nUse IP not listed in deny block: 10.0.0.2")
   262          resp2 = requests.get(
   263              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   264              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.2"},
   265          )
   266          print(f"Response: {resp2.status_code}\n{resp2.text}")
   267  
   268          delete_policy(kube_apis.custom_objects, deny_pol_name, v_s_route_setup.route_m.namespace)
   269          delete_policy(kube_apis.custom_objects, allow_pol_name, v_s_route_setup.route_m.namespace)
   270          self.restore_default_vsr(kube_apis, v_s_route_setup)
   271          assert (
   272              resp2.status_code == 403
   273              and "403 Forbidden" in resp2.text
   274              and resp1.status_code == 200
   275              and "Server address:" in resp1.text
   276          )
   277  
   278      def test_invalid_policy_vsr(
   279          self,
   280          kube_apis,
   281          crd_ingress_controller,
   282          v_s_route_app_setup,
   283          test_namespace,
   284          config_setup,
   285          v_s_route_setup,
   286      ):
   287          """
   288          Test if applying invalid-policy results in 500.
   289          """
   290          req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}"
   291          resp = requests.get(
   292              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   293              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   294          )
   295          print(f"Response: {resp.status_code}\n{resp.text}")
   296          assert resp.status_code == 200
   297  
   298          print(f"Create invalid policy")
   299          pol_name = create_policy_from_yaml(
   300              kube_apis.custom_objects, invalid_pol_src, v_s_route_setup.route_m.namespace
   301          )
   302          patch_v_s_route_from_yaml(
   303              kube_apis.custom_objects,
   304              v_s_route_setup.route_m.name,
   305              invalid_vsr_src,
   306              v_s_route_setup.route_m.namespace,
   307          )
   308          wait_before_test()
   309          policy_info = read_custom_resource(
   310              kube_apis.custom_objects, v_s_route_setup.route_m.namespace, "policies", pol_name
   311          )
   312  
   313          print(f"\nUse IP listed in deny block: 10.0.0.1")
   314          resp = requests.get(
   315              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   316              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   317          )
   318          print(f"Response: {resp.status_code}\n{resp.text}")
   319          vsr_info = read_custom_resource(
   320              kube_apis.custom_objects,
   321              v_s_route_setup.route_m.namespace,
   322              "virtualserverroutes",
   323              v_s_route_setup.route_m.name,
   324          )
   325          delete_policy(kube_apis.custom_objects, pol_name, v_s_route_setup.route_m.namespace)
   326          self.restore_default_vsr(kube_apis, v_s_route_setup)
   327          assert (
   328              policy_info["status"]
   329              and policy_info["status"]["reason"] == "Rejected"
   330              and policy_info["status"]["state"] == "Invalid"
   331          )
   332          assert resp.status_code == 500 and "500 Internal Server Error" in resp.text
   333          assert (
   334              vsr_info["status"]["state"] == "Warning"
   335              and vsr_info["status"]["reason"] == "AddedOrUpdatedWithWarning"
   336          )
   337  
   338      @pytest.mark.parametrize("src", [vs_spec_vsr_override_src, vs_route_vsr_override_src])
   339      def test_overide_vs_vsr(
   340          self,
   341          kube_apis,
   342          crd_ingress_controller,
   343          v_s_route_app_setup,
   344          test_namespace,
   345          config_setup,
   346          v_s_route_setup,
   347          src,
   348      ):
   349          """
   350          Test if vsr subroute policy overrides vs spec policy and vsr subroute policy overrides vs route policy
   351          """
   352          req_url = f"http://{v_s_route_setup.public_endpoint.public_ip}:{v_s_route_setup.public_endpoint.port}"
   353  
   354          print(f"Create deny policy")
   355          deny_pol_name = create_policy_from_yaml(
   356              kube_apis.custom_objects, deny_pol_src, v_s_route_setup.route_m.namespace
   357          )
   358          print(f"Create allow policy")
   359          allow_pol_name = create_policy_from_yaml(
   360              kube_apis.custom_objects, allow_pol_src, v_s_route_setup.route_m.namespace
   361          )
   362  
   363          patch_v_s_route_from_yaml(
   364              kube_apis.custom_objects,
   365              v_s_route_setup.route_m.name,
   366              allow_vsr_src,
   367              v_s_route_setup.route_m.namespace,
   368          )
   369          # patch vs with blocking policy
   370          patch_virtual_server_from_yaml(
   371              kube_apis.custom_objects, v_s_route_setup.vs_name, src, v_s_route_setup.namespace
   372          )
   373          wait_before_test()
   374  
   375          print(f"\nUse IP listed in deny block: 10.0.0.1")
   376          resp = requests.get(
   377              f"{req_url}{v_s_route_setup.route_m.paths[0]}",
   378              headers={"host": v_s_route_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   379          )
   380          print(f"Response: {resp.status_code}\n{resp.text}")
   381  
   382          delete_policy(kube_apis.custom_objects, deny_pol_name, v_s_route_setup.route_m.namespace)
   383          delete_policy(kube_apis.custom_objects, allow_pol_name, v_s_route_setup.route_m.namespace)
   384          self.restore_default_vsr(kube_apis, v_s_route_setup)
   385          patch_virtual_server_from_yaml(
   386              kube_apis.custom_objects, v_s_route_setup.vs_name, std_vs_src, v_s_route_setup.namespace
   387          )
   388          wait_before_test()
   389          assert resp.status_code == 200 and "Server address:" in resp.text