Merge "New test for services without selectors with NP."

This commit is contained in:
Zuul 2021-01-12 21:05:09 +00:00 committed by Gerrit Code Review
commit c022db0f75
3 changed files with 178 additions and 4 deletions

View File

@ -22,6 +22,7 @@ import time
from oslo_log import log as logging
import netaddr
import requests
import kubernetes
@ -724,12 +725,14 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest):
return False
@classmethod
def create_namespace(cls, name=None, wait_for_crd=True,
def create_namespace(cls, name=None, labels=None,
wait_for_crd=True,
timeout_period=consts.NS_TIMEOUT):
if not name:
name = data_utils.rand_name(prefix='kuryr-namespace')
namespace = cls.k8s_client.V1Namespace()
namespace.metadata = cls.k8s_client.V1ObjectMeta(name=name)
namespace.metadata = cls.k8s_client.V1ObjectMeta(name=name,
labels=labels)
namespace_obj = cls.k8s_client.CoreV1Api().create_namespace(
body=namespace)
@ -1331,3 +1334,12 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest):
protocol,
namespace_name=namespace)
return pod_name
def get_curl_template(self, ip_or_cidr, extra_args='', port=False):
ipn = netaddr.IPNetwork(ip_or_cidr)
curl_tmpl = "curl " + extra_args if extra_args else "curl"
curl_tmpl = (curl_tmpl + " [{}]"
if ipn.version == 6 else curl_tmpl + " {}")
return curl_tmpl + "{}" if port else curl_tmpl

View File

@ -146,6 +146,7 @@ class TestNetworkPolicyScenario(base.BaseKuryrScenarioTest,
def test_ipblock_network_policy_allow_except(self):
namespace_name, namespace = self.create_namespace()
self.addCleanup(self.delete_namespace, namespace_name)
if CONF.kuryr_kubernetes.kuryrnetworks:
cidr = self.get_kuryr_network_crds(
namespace_name)['status']['subnetCIDR']
@ -156,10 +157,10 @@ class TestNetworkPolicyScenario(base.BaseKuryrScenarioTest,
ipn = netaddr.IPNetwork(cidr)
max_prefixlen = "/32"
curl_tmpl = "curl {}{}"
if ipn.version == 6:
max_prefixlen = "/128"
curl_tmpl = "curl [{}]{}"
curl_tmpl = self.get_curl_template(cidr, extra_args='-m 5', port=True)
allow_all_cidr = cidr
pod_ip_list = []

View File

@ -13,15 +13,18 @@
# limitations under the License.
import json
import time
import kubernetes
from oslo_log import log as logging
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from kuryr_tempest_plugin.tests.scenario import base
from kuryr_tempest_plugin.tests.scenario import base_network_policy as base_np
from kuryr_tempest_plugin.tests.scenario import consts
LOG = logging.getLogger(__name__)
CONF = config.CONF
@ -173,3 +176,161 @@ class NetworkPolicyScenario(base_np.TestNetworkPolicyScenario):
return (crd['status'].get('securityGroupId'),
crd['status'].get('podSelector'),
expected == existing)
class ServiceWOSelectorsNPScenario(base.BaseKuryrScenarioTest):
@classmethod
def skip_checks(cls):
super(ServiceWOSelectorsNPScenario, cls).skip_checks()
if not CONF.kuryr_kubernetes.network_policy_enabled:
raise cls.skipException('Network Policy driver and handler must '
'be enabled to run this tests')
if not CONF.kuryr_kubernetes.test_services_without_selector:
raise cls.skipException("Service without selectors tests are not "
"enabled")
if not CONF.kuryr_kubernetes.new_kuryrnetworkpolicy_crd:
raise cls.skipException('New KuryrNetworkPolicy NP CRDs must be '
'used to run these tests')
def get_np_crd_info(self, name, namespace='default', **kwargs):
crd = self.k8s_client.CustomObjectsApi().get_namespaced_custom_object(
group=base.KURYR_CRD_GROUP, version=base.KURYR_CRD_VERSION,
namespace=namespace, plural=KURYR_NETWORK_POLICY_CRD_PLURAL,
name=name, **kwargs)
expected = len(crd['spec'].get('egressSgRules', []) +
crd['spec'].get('ingressSgRules', []))
existing = len(crd['status']['securityGroupRules'])
# Third result tells us if all the SG rules are created.
return (crd['status'].get('securityGroupId'),
crd['status'].get('podSelector'),
expected == existing)
@decorators.idempotent_id('abcfa34d-078c-485f-a80d-765c173d7652')
def test_egress_np_to_service_wo_selectors(self):
# create namespace for client
client_ns_name = data_utils.rand_name(prefix='client-ns')
client_label = {'app': data_utils.rand_name('client')}
self.create_namespace(name=client_ns_name)
self.addCleanup(self.delete_namespace, client_ns_name)
# create client pod in client ns
client_pod_name = data_utils.rand_name(prefix='client-pod')
self.create_pod(namespace=client_ns_name, name=client_pod_name,
labels=client_label)
# create ns for server
server_ns_name = data_utils.rand_name(prefix='server-ns')
server_label = {'app': data_utils.rand_name('server')}
self.create_namespace(name=server_ns_name, labels=server_label)
self.addCleanup(self.delete_namespace, server_ns_name)
# create server pod under it
server_pod_name = data_utils.rand_name(prefix='server-pod')
self.create_pod(namespace=server_ns_name, name=server_pod_name,
labels=server_label)
server_pod_addr = self.get_pod_ip(server_pod_name,
namespace=server_ns_name)
# create another server pod with different label
server2_label = {'app': data_utils.rand_name('server2')}
server2_pod_name = data_utils.rand_name(prefix='server2-pod')
self.create_pod(namespace=server_ns_name, name=server2_pod_name,
labels=server2_label)
server2_pod_addr = self.get_pod_ip(server2_pod_name,
namespace=server_ns_name)
# create service w/o selectors
service_name, _ = self.create_service(namespace=server_ns_name,
pod_label=None)
# manually create endpoint for the service
endpoint = self.k8s_client.V1Endpoints()
endpoint.metadata = self.k8s_client.V1ObjectMeta(name=service_name)
addresses = [self.k8s_client.V1EndpointAddress(ip=server_pod_addr)]
endpoint.subsets = [self.k8s_client.V1EndpointSubset(
addresses=addresses,
ports=[self.k8s_client.V1EndpointPort(
name=None, port=8080, protocol='TCP')])]
self.k8s_client.CoreV1Api().create_namespaced_endpoints(
namespace=server_ns_name, body=endpoint)
# create another service
service2_name, _ = self.create_service(namespace=server_ns_name,
pod_label=None)
# manually create endpoint for the service
endpoint = self.k8s_client.V1Endpoints()
endpoint.metadata = self.k8s_client.V1ObjectMeta(name=service2_name)
addresses = [self.k8s_client.V1EndpointAddress(ip=server2_pod_addr)]
endpoint.subsets = [self.k8s_client.V1EndpointSubset(
addresses=addresses,
ports=[self.k8s_client.V1EndpointPort(
name=None, port=8080, protocol='TCP')])]
self.k8s_client.CoreV1Api().create_namespaced_endpoints(
namespace=server_ns_name, body=endpoint)
# check endpoints configured
service_ip = self.get_service_ip(service_name,
namespace=server_ns_name)
service2_ip = self.get_service_ip(service2_name,
namespace=server_ns_name)
self.verify_lbaas_endpoints_configured(service_name, 1, server_ns_name)
self.verify_lbaas_endpoints_configured(service2_name, 1,
server_ns_name)
# check connectivity
curl_tmpl = self.get_curl_template(service_ip, extra_args='-m 10')
cmd = ["/bin/sh", "-c", curl_tmpl.format(service_ip)]
cmd2 = ["/bin/sh", "-c", curl_tmpl.format(service2_ip)]
self.assertIn(consts.POD_OUTPUT,
self.exec_command_in_pod(client_pod_name, cmd,
namespace=client_ns_name))
self.assertIn(consts.POD_OUTPUT,
self.exec_command_in_pod(client_pod_name, cmd2,
namespace=client_ns_name))
# create NP for client to be able to reach server
np_name = data_utils.rand_name(prefix='kuryr-np')
np = self.k8s_client.V1NetworkPolicy()
np.kind = 'NetworkPolicy'
np.api_version = 'networking.k8s.io/v1'
np.metadata = self.k8s_client.V1ObjectMeta(name=np_name,
namespace=client_ns_name)
to = self.k8s_client.V1NetworkPolicyPeer(
pod_selector=self.k8s_client.V1LabelSelector(
match_labels=server_label),
namespace_selector=self.k8s_client.V1LabelSelector(
match_labels=server_label))
np.spec = self.k8s_client.V1NetworkPolicySpec(
pod_selector=self.k8s_client.V1LabelSelector(
match_labels=client_label),
policy_types=['Egress'],
egress=[self.k8s_client.V1NetworkPolicyEgressRule(to=[to])])
np = (self.k8s_client.NetworkingV1Api()
.create_namespaced_network_policy(namespace=client_ns_name,
body=np))
self.addCleanup(self.delete_network_policy, np.metadata.name,
client_ns_name)
start = time.time()
while time.time() - start < TIMEOUT_PERIOD:
try:
time.sleep(1)
_, crd_pod_selector, _ = self.get_np_crd_info(np_name)
if crd_pod_selector:
break
except kubernetes.client.rest.ApiException:
continue
# after applying NP, we still should have an access from client to the
# service with matched labels,
self.assertIn(consts.POD_OUTPUT,
self.exec_command_in_pod(client_pod_name, cmd,
namespace=client_ns_name))
# while for the other service, we should not.
self.assertNotIn(consts.POD_OUTPUT,
self.exec_command_in_pod(client_pod_name, cmd2,
namespace=client_ns_name))