From 8db1cbc44c430a65978625ba61941bc050dbbe50 Mon Sep 17 00:00:00 2001 From: Luis Tomas Bolivar Date: Wed, 1 Aug 2018 13:26:07 +0200 Subject: [PATCH] Namespace svc isolation tempest coverage It extends the namespace tests to also ensure proper services isolation between namespaces. It creates pods and services in different namespaces and checks that traffic is blocked between them, unless it is the default namespace, which can reach all the services regardless of the namespaces. Depends-On: I7b78e12cdf2bce5d0780e582814ef51ef0c459a7 Change-Id: I460eb37415fa6d864c68e29ee79abdc8d1760c61 Implements: blueprint openshift-project-isolation-support --- .../tests/scenario/test_cross_ping.py | 23 ++++-- .../tests/scenario/test_namespace.py | 79 +++++++++++++++++++ 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/kuryr_tempest_plugin/tests/scenario/test_cross_ping.py b/kuryr_tempest_plugin/tests/scenario/test_cross_ping.py index 829d22e2..ceeba047 100644 --- a/kuryr_tempest_plugin/tests/scenario/test_cross_ping.py +++ b/kuryr_tempest_plugin/tests/scenario/test_cross_ping.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import time - from oslo_log import log as logging from tempest import config from tempest.lib.common.utils import data_utils @@ -67,6 +65,20 @@ class TestCrossPingScenario(base.BaseKuryrScenarioTest): except exceptions.SSHExecCommandFailed: LOG.error("Couldn't ping server") + @decorators.idempotent_id('bddf5441-1244-449d-a125-b5fddfb1a1a8') + def test_pod_vm_ping(self): + keypair = self.create_keypair() + security_groups = [ + {'name': self._create_security_group()['name']} + ] + server = self.create_server(name=data_utils.rand_name(prefix='kuryr'), + key_name=keypair['name'], + security_groups=security_groups) + fip = self.create_floating_ip(server) + + pod_name, pod = self.create_pod() + self.addCleanup(self.delete_pod, pod_name, pod) + # check connectivity from Pod to VM cmd = [ "/bin/sh", "-c", "ping -c 4 {dst_ip}>/dev/null ; echo $?".format( @@ -75,15 +87,14 @@ class TestCrossPingScenario(base.BaseKuryrScenarioTest): @decorators.idempotent_id('bddf5441-1244-449d-a125-b5fddfb1a2a9') def test_pod_pod_ping(self): - pod_name_list, pod_fip_list = [], [] + pod_name_list = [] for i in range(2): pod_name, pod = self.create_pod() self.addCleanup(self.delete_pod, pod_name, pod) pod_name_list.append(pod_name) - pod_fip_list.append(self.assign_fip_to_pod(pod_name)) + pod_ip = self.get_pod_ip(pod_name_list[1]) cmd = [ "/bin/sh", "-c", "ping -c 4 {dst_ip}>/dev/null ; echo $?".format( - dst_ip=pod_fip_list[1]['floatingip']['floating_ip_address'])] - time.sleep(20) + dst_ip=pod_ip)] self.assertEqual(self.exec_command_in_pod(pod_name_list[0], cmd), '0') diff --git a/kuryr_tempest_plugin/tests/scenario/test_namespace.py b/kuryr_tempest_plugin/tests/scenario/test_namespace.py index 32c42d8c..73f11f44 100644 --- a/kuryr_tempest_plugin/tests/scenario/test_namespace.py +++ b/kuryr_tempest_plugin/tests/scenario/test_namespace.py @@ -159,6 +159,85 @@ class TestNamespaceScenario(base.BaseKuryrScenarioTest): self._delete_namespace_resources(ns2_name, net_crd_ns2, subnet_ns2_name) + def test_namespace_sg_svc_isolation(self): + # Check security group resources are created + ns1_name, ns1 = self.create_namespace() + ns2_name, ns2 = self.create_namespace() + + existing_namespaces = [ns.metadata.name + for ns in self.list_namespaces().items] + + self.assertIn(ns1_name, existing_namespaces) + self.assertIn(ns2_name, existing_namespaces) + self.assertIn('default', existing_namespaces) + + subnet_ns1_name = 'ns/' + ns1_name + '-subnet' + subnet_ns2_name = 'ns/' + ns2_name + '-subnet' + net_crd_ns1_name = 'ns-' + ns1_name + net_crd_ns2_name = 'ns-' + ns2_name + + net_crd_ns1 = self.get_kuryr_net_crds(net_crd_ns1_name) + net_crd_ns2 = self.get_kuryr_net_crds(net_crd_ns2_name) + + self.assertIn(net_crd_ns1_name, net_crd_ns1['metadata']['name']) + self.assertIn(net_crd_ns2_name, net_crd_ns2['metadata']['name']) + + seen_sgs = self.os_admin.security_groups_client.list_security_groups() + seen_sg_ids = [sg['id'] for sg in seen_sgs['security_groups']] + + self.assertIn(net_crd_ns1['spec']['sgId'], seen_sg_ids) + self.assertIn(net_crd_ns2['spec']['sgId'], seen_sg_ids) + + # Create pods and services in different namespaces + pod_ns1_name, pod_ns1 = self.create_pod(labels={"app": 'pod-label'}, + namespace=ns1_name) + svc_ns1_name, _ = self.create_service( + pod_label=pod_ns1.metadata.labels, namespace=ns1_name) + svc_ns1_ip = self.get_service_ip(service_name=svc_ns1_name, + namespace=ns1_name) + + pod_ns2_name, pod_ns2 = self.create_pod(labels={"app": 'pod-label'}, + namespace=ns2_name) + svc_ns2_name, _ = self.create_service( + pod_label=pod_ns2.metadata.labels, namespace=ns2_name) + svc_ns2_ip = self.get_service_ip(service_name=svc_ns2_name, + namespace=ns2_name) + + # Wait for services to be ready + self.wait_service_status(svc_ns1_ip, + CONF.kuryr_kubernetes.lb_build_timeout) + self.wait_service_status(svc_ns2_ip, + CONF.kuryr_kubernetes.lb_build_timeout) + + pod_nsdefault_name, pod_nsdefault = self.create_pod( + labels={"app": 'pod-label'}, namespace='default') + self.addCleanup(self.delete_pod, pod_nsdefault_name) + + # Check namespace svc connectivity and isolation + # check connectivity from NS1 pod to NS1 service + cmd = ["/bin/sh", "-c", "curl {dst_ip}".format( + dst_ip=svc_ns1_ip)] + self.assertIn('HELLO! I AM ALIVE!!!', + self.exec_command_in_pod(pod_ns1_name, cmd, ns1_name)) + + # check no connectivity from NS1 pod to NS2 service + cmd = ["/bin/sh", "-c", "curl {dst_ip}".format( + dst_ip=svc_ns2_ip)] + self.assertNotIn('HELLO! I AM ALIVE!!!', + self.exec_command_in_pod(pod_ns1_name, cmd, ns1_name)) + + # check connectivity from default pod to NS2 service + cmd = ["/bin/sh", "-c", "curl {dst_ip}".format( + dst_ip=svc_ns2_ip)] + self.assertIn('HELLO! I AM ALIVE!!!', + self.exec_command_in_pod(pod_nsdefault_name, cmd)) + + # Check resources are deleted + self._delete_namespace_resources(ns1_name, net_crd_ns1, + subnet_ns1_name) + self._delete_namespace_resources(ns2_name, net_crd_ns2, + subnet_ns2_name) + def _delete_namespace_resources(self, namespace, net_crd, subnet): # Check resources are deleted self.delete_namespace(namespace)