github.com/nginxinc/kubernetes-ingress@v1.12.5/tests/suite/test_ac_policies.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      create_policy_from_yaml,
    10      delete_policy,
    11      read_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}/access-control/standard/virtual-server.yaml"
    18  deny_pol_src = f"{TEST_DATA}/access-control/policies/access-control-policy-deny.yaml"
    19  deny_vs_src = f"{TEST_DATA}/access-control/spec/virtual-server-deny.yaml"
    20  allow_pol_src = f"{TEST_DATA}/access-control/policies/access-control-policy-allow.yaml"
    21  allow_vs_src = f"{TEST_DATA}/access-control/spec/virtual-server-allow.yaml"
    22  override_vs_src = f"{TEST_DATA}/access-control/spec/virtual-server-override.yaml"
    23  invalid_pol_src = f"{TEST_DATA}/access-control/policies/access-control-policy-invalid.yaml"
    24  invalid_vs_src = f"{TEST_DATA}/access-control/spec/virtual-server-invalid.yaml"
    25  allow_vs_src_route = f"{TEST_DATA}/access-control/route-subroute/virtual-server-allow-route.yaml"
    26  deny_vs_src_route = f"{TEST_DATA}/access-control/route-subroute/virtual-server-deny-route.yaml"
    27  invalid_vs_src_route = (
    28      f"{TEST_DATA}/access-control/route-subroute/virtual-server-invalid-route.yaml"
    29  )
    30  override_vs_src_route = (
    31      f"{TEST_DATA}/access-control/route-subroute/virtual-server-override-route.yaml"
    32  )
    33  override_vs_spec_route_src = (
    34      f"{TEST_DATA}/access-control/route-subroute/virtual-server-override-spec-route.yaml"
    35  )
    36  
    37  
    38  @pytest.fixture(scope="class")
    39  def config_setup(request, kube_apis, ingress_controller_prerequisites) -> None:
    40      """
    41      Replace configmap to add "set-real-ip-from"
    42      :param request: pytest fixture
    43      :param kube_apis: client apis
    44      :param ingress_controller_prerequisites: IC pre-requisites
    45      """
    46      print(f"------------- Replace ConfigMap --------------")
    47      replace_configmap_from_yaml(
    48          kube_apis.v1,
    49          ingress_controller_prerequisites.config_map["metadata"]["name"],
    50          ingress_controller_prerequisites.namespace,
    51          test_cm_src,
    52      )
    53  
    54      def fin():
    55          print(f"------------- Restore ConfigMap --------------")
    56          replace_configmap_from_yaml(
    57              kube_apis.v1,
    58              ingress_controller_prerequisites.config_map["metadata"]["name"],
    59              ingress_controller_prerequisites.namespace,
    60              std_cm_src,
    61          )
    62  
    63      request.addfinalizer(fin)
    64  
    65  
    66  @pytest.mark.policies
    67  @pytest.mark.parametrize(
    68      "crd_ingress_controller, virtual_server_setup",
    69      [
    70          (
    71              {
    72                  "type": "complete",
    73                  "extra_args": [f"-enable-custom-resources", f"-enable-leader-election=false"],
    74              },
    75              {"example": "access-control", "app_type": "simple",},
    76          )
    77      ],
    78      indirect=True,
    79  )
    80  class TestAccessControlPoliciesVs:
    81      def restore_default_vs(self, kube_apis, virtual_server_setup) -> None:
    82          """
    83          Restore VirtualServer without policy spec
    84          """
    85          delete_virtual_server(
    86              kube_apis.custom_objects, virtual_server_setup.vs_name, virtual_server_setup.namespace
    87          )
    88          create_virtual_server_from_yaml(
    89              kube_apis.custom_objects, std_vs_src, virtual_server_setup.namespace
    90          )
    91          wait_before_test()
    92  
    93      @pytest.mark.parametrize("src", [deny_vs_src, deny_vs_src_route])
    94      @pytest.mark.smoke
    95      def test_deny_policy(
    96          self,
    97          kube_apis,
    98          crd_ingress_controller,
    99          virtual_server_setup,
   100          test_namespace,
   101          config_setup,
   102          src,
   103      ):
   104          """
   105          Test if ip (10.0.0.1) block-listing is working: default(no policy) -> deny
   106          """
   107          resp = requests.get(
   108              virtual_server_setup.backend_1_url,
   109              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   110          )
   111          print(f"Response: {resp.status_code}\n{resp.text}")
   112          assert resp.status_code == 200
   113  
   114          print(f"Create deny policy")
   115          pol_name = create_policy_from_yaml(kube_apis.custom_objects, deny_pol_src, test_namespace)
   116          print(f"Patch vs with policy: {src}")
   117          patch_virtual_server_from_yaml(
   118              kube_apis.custom_objects,
   119              virtual_server_setup.vs_name,
   120              src,
   121              virtual_server_setup.namespace,
   122          )
   123          wait_before_test()
   124  
   125          policy_info = read_custom_resource(kube_apis.custom_objects, test_namespace, "policies", pol_name)
   126          print(f"\nUse IP listed in deny block: 10.0.0.1")
   127          resp1 = requests.get(
   128              virtual_server_setup.backend_1_url,
   129              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   130          )
   131          print(f"Response: {resp1.status_code}\n{resp1.text}")
   132          print(f"\nUse IP not listed in deny block: 10.0.0.2")
   133          resp2 = requests.get(
   134              virtual_server_setup.backend_1_url,
   135              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.2"},
   136          )
   137          print(f"Response: {resp2.status_code}\n{resp2.text}")
   138  
   139          delete_policy(kube_apis.custom_objects, pol_name, test_namespace)
   140          self.restore_default_vs(kube_apis, virtual_server_setup)
   141  
   142          assert (
   143              policy_info["status"]
   144              and policy_info["status"]["reason"] == "AddedOrUpdated"
   145              and policy_info["status"]["state"] == "Valid"
   146          )
   147  
   148          assert (
   149              resp1.status_code == 403
   150              and "403 Forbidden" in resp1.text
   151              and resp2.status_code == 200
   152              and "Server address:" in resp2.text
   153          )
   154  
   155      @pytest.mark.parametrize("src", [allow_vs_src, allow_vs_src_route])
   156      @pytest.mark.smoke
   157      def test_allow_policy(
   158          self,
   159          kube_apis,
   160          crd_ingress_controller,
   161          virtual_server_setup,
   162          test_namespace,
   163          config_setup,
   164          src,
   165      ):
   166          """
   167          Test if ip (10.0.0.1) allow-listing is working: default(no policy) -> allow
   168          """
   169          resp = requests.get(
   170              virtual_server_setup.backend_1_url,
   171              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   172          )
   173          print(f"Response: {resp.status_code}\n{resp.text}")
   174          assert resp.status_code == 200
   175  
   176          print(f"Create allow policy")
   177          pol_name = create_policy_from_yaml(kube_apis.custom_objects, allow_pol_src, test_namespace)
   178          patch_virtual_server_from_yaml(
   179              kube_apis.custom_objects,
   180              virtual_server_setup.vs_name,
   181              src,
   182              virtual_server_setup.namespace,
   183          )
   184          wait_before_test()
   185  
   186          policy_info = read_custom_resource(kube_apis.custom_objects, test_namespace, "policies", pol_name)
   187          print(f"\nUse IP listed in allow block: 10.0.0.1")
   188          resp1 = requests.get(
   189              virtual_server_setup.backend_1_url,
   190              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   191          )
   192          print(f"\nUse IP listed not in allow block: 10.0.0.2")
   193          print(f"Response: {resp1.status_code}\n{resp1.text}")
   194          resp2 = requests.get(
   195              virtual_server_setup.backend_1_url,
   196              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.2"},
   197          )
   198          print(f"Response: {resp2.status_code}\n{resp2.text}")
   199  
   200          delete_policy(kube_apis.custom_objects, pol_name, test_namespace)
   201          self.restore_default_vs(kube_apis, virtual_server_setup)
   202  
   203          assert (
   204              policy_info["status"]
   205              and policy_info["status"]["reason"] == "AddedOrUpdated"
   206              and policy_info["status"]["state"] == "Valid"
   207          )
   208  
   209          assert (
   210              resp1.status_code == 200
   211              and "Server address:" in resp1.text
   212              and resp2.status_code == 403
   213              and "403 Forbidden" in resp2.text
   214          )
   215  
   216      @pytest.mark.parametrize("src", [override_vs_src, override_vs_src_route])
   217      def test_override_policy(
   218          self,
   219          kube_apis,
   220          crd_ingress_controller,
   221          virtual_server_setup,
   222          test_namespace,
   223          config_setup,
   224          src,
   225      ):
   226          """
   227          Test if ip allow-listing overrides block-listing: default(no policy) -> deny and allow
   228          """
   229          resp = requests.get(
   230              virtual_server_setup.backend_1_url,
   231              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   232          )
   233          print(f"Response: {resp.status_code}\n{resp.text}")
   234          assert resp.status_code == 200
   235  
   236          print(f"Create deny policy")
   237          deny_pol_name = create_policy_from_yaml(
   238              kube_apis.custom_objects, deny_pol_src, test_namespace
   239          )
   240          print(f"Create allow policy")
   241          allow_pol_name = create_policy_from_yaml(
   242              kube_apis.custom_objects, allow_pol_src, test_namespace
   243          )
   244          patch_virtual_server_from_yaml(
   245              kube_apis.custom_objects,
   246              virtual_server_setup.vs_name,
   247              src,
   248              virtual_server_setup.namespace,
   249          )
   250          wait_before_test()
   251  
   252          print(f"Use IP listed in both deny and allow policies: 10.0.0.1")
   253          resp = requests.get(
   254              virtual_server_setup.backend_1_url,
   255              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   256          )
   257          print(f"Response: {resp.status_code}\n{resp.text}")
   258  
   259          delete_policy(kube_apis.custom_objects, deny_pol_name, test_namespace)
   260          delete_policy(kube_apis.custom_objects, allow_pol_name, test_namespace)
   261          self.restore_default_vs(kube_apis, virtual_server_setup)
   262  
   263          assert resp.status_code == 200 and "Server address:" in resp.text
   264  
   265      @pytest.mark.parametrize("src", [invalid_vs_src, invalid_vs_src_route])
   266      def test_invalid_policy(
   267          self,
   268          kube_apis,
   269          crd_ingress_controller,
   270          virtual_server_setup,
   271          test_namespace,
   272          config_setup,
   273          src,
   274      ):
   275          """
   276          Test if invalid policy is applied then response is 500
   277          """
   278          resp = requests.get(
   279              virtual_server_setup.backend_1_url,
   280              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   281          )
   282          print(f"Response: {resp.status_code}\n{resp.text}")
   283          assert resp.status_code == 200
   284  
   285          print(f"Create invalid policy")
   286          invalid_pol_name = create_policy_from_yaml(
   287              kube_apis.custom_objects, invalid_pol_src, test_namespace
   288          )
   289          patch_virtual_server_from_yaml(
   290              kube_apis.custom_objects,
   291              virtual_server_setup.vs_name,
   292              src,
   293              virtual_server_setup.namespace,
   294          )
   295  
   296          wait_before_test()
   297          resp = requests.get(
   298              virtual_server_setup.backend_1_url,
   299              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   300          )
   301          print(f"Response: {resp.status_code}\n{resp.text}")
   302  
   303          vs_info = read_custom_resource(
   304              kube_apis.custom_objects,
   305              virtual_server_setup.namespace,
   306              "virtualservers",
   307              virtual_server_setup.vs_name,
   308          )
   309          policy_info = read_custom_resource(
   310              kube_apis.custom_objects, test_namespace, "policies", invalid_pol_name
   311          )
   312          delete_policy(kube_apis.custom_objects, invalid_pol_name, test_namespace)
   313          self.restore_default_vs(kube_apis, virtual_server_setup)
   314  
   315          assert resp.status_code == 500 and "500 Internal Server Error" in resp.text
   316          assert (
   317              policy_info["status"]
   318              and policy_info["status"]["reason"] == "Rejected"
   319              and policy_info["status"]["state"] == "Invalid"
   320          )
   321          assert (
   322              vs_info["status"]["state"] == "Warning"
   323              and vs_info["status"]["reason"] == "AddedOrUpdatedWithWarning"
   324          )
   325  
   326      @pytest.mark.parametrize("src", [deny_vs_src, deny_vs_src_route])
   327      def test_deleted_policy(
   328          self,
   329          kube_apis,
   330          crd_ingress_controller,
   331          virtual_server_setup,
   332          test_namespace,
   333          config_setup,
   334          src,
   335      ):
   336          """
   337          Test if valid policy is deleted then response is 500
   338          """
   339          resp = requests.get(
   340              virtual_server_setup.backend_1_url,
   341              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   342          )
   343          print(f"Response: {resp.status_code}\n{resp.text}")
   344          assert resp.status_code == 200
   345  
   346          print(f"Create deny policy")
   347          pol_name = create_policy_from_yaml(kube_apis.custom_objects, deny_pol_src, test_namespace)
   348          patch_virtual_server_from_yaml(
   349              kube_apis.custom_objects,
   350              virtual_server_setup.vs_name,
   351              src,
   352              virtual_server_setup.namespace,
   353          )
   354  
   355          wait_before_test()
   356          vs_info = read_custom_resource(
   357              kube_apis.custom_objects,
   358              virtual_server_setup.namespace,
   359              "virtualservers",
   360              virtual_server_setup.vs_name,
   361          )
   362          assert vs_info["status"]["state"] == "Valid"
   363          delete_policy(kube_apis.custom_objects, pol_name, test_namespace)
   364  
   365          wait_before_test()
   366          resp = requests.get(
   367              virtual_server_setup.backend_1_url,
   368              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   369          )
   370          print(f"Response: {resp.status_code}\n{resp.text}")
   371  
   372          vs_info = read_custom_resource(
   373              kube_apis.custom_objects,
   374              virtual_server_setup.namespace,
   375              "virtualservers",
   376              virtual_server_setup.vs_name,
   377          )
   378          self.restore_default_vs(kube_apis, virtual_server_setup)
   379  
   380          assert resp.status_code == 500 and "500 Internal Server Error" in resp.text
   381          assert (
   382              vs_info["status"]["state"] == "Warning"
   383              and vs_info["status"]["reason"] == "AddedOrUpdatedWithWarning"
   384          )
   385  
   386      def test_route_override_spec(
   387          self, kube_apis, crd_ingress_controller, virtual_server_setup, test_namespace, config_setup,
   388      ):
   389          """
   390          Test allow policy specified under routes overrides block in spec
   391          """
   392          resp = requests.get(
   393              virtual_server_setup.backend_1_url,
   394              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   395          )
   396          print(f"Response: {resp.status_code}\n{resp.text}")
   397          assert resp.status_code == 200
   398  
   399          print(f"Create deny policy")
   400          deny_pol_name = create_policy_from_yaml(
   401              kube_apis.custom_objects, deny_pol_src, test_namespace
   402          )
   403          print(f"Create allow policy")
   404          allow_pol_name = create_policy_from_yaml(
   405              kube_apis.custom_objects, allow_pol_src, test_namespace
   406          )
   407  
   408          patch_virtual_server_from_yaml(
   409              kube_apis.custom_objects,
   410              virtual_server_setup.vs_name,
   411              override_vs_spec_route_src,
   412              virtual_server_setup.namespace,
   413          )
   414          wait_before_test()
   415  
   416          print(f"Use IP listed in both deny and allow policies: 10.0.0.1")
   417          resp = requests.get(
   418              virtual_server_setup.backend_1_url,
   419              headers={"host": virtual_server_setup.vs_host, "X-Real-IP": "10.0.0.1"},
   420          )
   421          print(f"Response: {resp.status_code}\n{resp.text}")
   422  
   423          self.restore_default_vs(kube_apis, virtual_server_setup)
   424          delete_policy(kube_apis.custom_objects, deny_pol_name, test_namespace)
   425          delete_policy(kube_apis.custom_objects, allow_pol_name, test_namespace)
   426  
   427          assert resp.status_code == 200 and "Server address:" in resp.text