diff --git a/kuryr_kubernetes/controller/drivers/nested_macvlan_vif.py b/kuryr_kubernetes/controller/drivers/nested_macvlan_vif.py index a6d7560a0..ac28ae56d 100755 --- a/kuryr_kubernetes/controller/drivers/nested_macvlan_vif.py +++ b/kuryr_kubernetes/controller/drivers/nested_macvlan_vif.py @@ -47,7 +47,8 @@ class NestedMacvlanPodVIFDriver(nested_vif.NestedPodVIFDriver): if not container_port: container_port = os_net.create_port(**req) self._check_port_binding([container_port]) - utils.tag_neutron_resources([container_port]) + if not self._tag_on_creation: + utils.tag_neutron_resources([container_port]) container_mac = container_port.mac_address container_ips = frozenset(entry['ip_address'] for entry in diff --git a/kuryr_kubernetes/controller/drivers/nested_vlan_vif.py b/kuryr_kubernetes/controller/drivers/nested_vlan_vif.py index a66fa948c..3eb7b98a9 100644 --- a/kuryr_kubernetes/controller/drivers/nested_vlan_vif.py +++ b/kuryr_kubernetes/controller/drivers/nested_vlan_vif.py @@ -17,6 +17,7 @@ from kuryr.lib import constants as kl_const from kuryr.lib import exceptions as kl_exc from kuryr.lib import segmentation_type_drivers as seg_driver from openstack import exceptions as os_exc +from oslo_config import cfg from oslo_log import log as logging from kuryr_kubernetes import clients @@ -33,6 +34,8 @@ LOG = logging.getLogger(__name__) DEFAULT_MAX_RETRY_COUNT = 3 DEFAULT_RETRY_INTERVAL = 1 +CONF = cfg.CONF + class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver): """Manages ports for nested-containers using VLANs to provide VIFs.""" @@ -45,7 +48,8 @@ class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver): rq = self._get_port_request(pod, project_id, subnets, security_groups) port = os_net.create_port(**rq) self._check_port_binding([port]) - utils.tag_neutron_resources([port]) + if not self._tag_on_creation: + utils.tag_neutron_resources([port]) vlan_id = self._add_subport(trunk_id, port.id) return ovu.neutron_to_osvif_vif_nested_vlan(port, subnets, vlan_id) @@ -87,7 +91,8 @@ class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver): LOG.exception("Error creating bulk ports: %s", bulk_port_rq) raise self._check_port_binding(ports) - utils.tag_neutron_resources(ports) + if not self._tag_on_creation: + utils.tag_neutron_resources(ports) for index, port in enumerate(ports): subports_info[index]['port_id'] = port['id'] @@ -139,6 +144,11 @@ class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver): if security_groups: port_req_body['security_groups'] = security_groups + if self._tag_on_creation: + tags = CONF.neutron_defaults.resource_tags + if tags: + port_req_body['tags'] = tags + return port_req_body def _create_subports_info(self, pod, project_id, subnets, @@ -149,7 +159,7 @@ class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver): in_use_vlan_ids = self._get_in_use_vlan_ids_set(trunk_id) port_rq = self._get_port_request(pod, project_id, subnets, security_groups, unbound) - for i in range(num_ports): + for _ in range(num_ports): try: vlan_id = seg_driver.allocate_segmentation_id(in_use_vlan_ids) except kl_exc.SegmentationIdAllocationFailure: @@ -194,7 +204,7 @@ class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver): raise subport = [{'segmentation_id': vlan_id, 'port_id': subport, - 'segmentation_type': 'vlan'}] + 'segmentation_type': 'vlan'}] try: os_net.add_trunk_subports(trunk_id, subport) except os_exc.ConflictException: diff --git a/kuryr_kubernetes/controller/drivers/neutron_vif.py b/kuryr_kubernetes/controller/drivers/neutron_vif.py index ca94d57da..eef5d7a91 100644 --- a/kuryr_kubernetes/controller/drivers/neutron_vif.py +++ b/kuryr_kubernetes/controller/drivers/neutron_vif.py @@ -15,6 +15,7 @@ from kuryr.lib import constants as kl_const from openstack import exceptions as os_exc +from oslo_config import cfg from oslo_log import log as logging from kuryr_kubernetes import clients @@ -28,10 +29,23 @@ from kuryr_kubernetes import os_vif_util as ovu LOG = logging.getLogger(__name__) +CONF = cfg.CONF + class NeutronPodVIFDriver(base.PodVIFDriver): """Manages normal Neutron ports to provide VIFs for Kubernetes Pods.""" + def __init__(self): + super(NeutronPodVIFDriver, self).__init__() + + self._tag_on_creation = utils.check_tag_on_creation() + if self._tag_on_creation: + LOG.info('Neutron supports tagging during bulk port creation.') + else: + LOG.warning('Neutron does not support tagging during bulk ' + 'port creation. Kuryr will tag resources after ' + 'port creation.') + def request_vif(self, pod, project_id, subnets, security_groups): os_net = clients.get_network_client() @@ -39,7 +53,8 @@ class NeutronPodVIFDriver(base.PodVIFDriver): port = os_net.create_port(**rq) self._check_port_binding([port]) - utils.tag_neutron_resources([port]) + if not self._tag_on_creation: + utils.tag_neutron_resources([port]) return ovu.neutron_to_osvif_vif(port.binding_vif_type, port, subnets) def request_vifs(self, pod, project_id, subnets, security_groups, @@ -67,7 +82,8 @@ class NeutronPodVIFDriver(base.PodVIFDriver): vif_plugin = port_info.binding_vif_type self._check_port_binding(ports) - utils.tag_neutron_resources(ports) + if not self._tag_on_creation: + utils.tag_neutron_resources(ports) vifs = [] for port in ports: vif = ovu.neutron_to_osvif_vif(vif_plugin, port, subnets) @@ -125,6 +141,11 @@ class NeutronPodVIFDriver(base.PodVIFDriver): if security_groups: port_req_body['security_groups'] = security_groups + if self._tag_on_creation: + tags = CONF.neutron_defaults.resource_tags + if tags: + port_req_body['tags'] = tags + return port_req_body def _check_port_binding(self, ports): diff --git a/kuryr_kubernetes/controller/drivers/sriov.py b/kuryr_kubernetes/controller/drivers/sriov.py index d3411417f..b16eeef0b 100644 --- a/kuryr_kubernetes/controller/drivers/sriov.py +++ b/kuryr_kubernetes/controller/drivers/sriov.py @@ -13,6 +13,7 @@ # under the License. from kuryr.lib import constants as kl_const +from oslo_config import cfg from oslo_log import log as logging from kuryr_kubernetes import clients @@ -23,6 +24,7 @@ from kuryr_kubernetes.controller.drivers import utils as c_utils from kuryr_kubernetes import os_vif_util as ovu LOG = logging.getLogger(__name__) +CONF = cfg.CONF def sriov_make_resource(prefix, res_name): @@ -57,7 +59,8 @@ class SriovVIFDriver(neutron_vif.NeutronPodVIFDriver): port = os_net.create_port(**rq) self._check_port_binding([port]) - c_utils.tag_neutron_resources([port]) + if not self._tag_on_creation: + c_utils.tag_neutron_resources([port]) vif = ovu.neutron_to_osvif_vif(vif_plugin, port, subnets) vif.physnet = physnet vif.pod_name = pod_name @@ -178,4 +181,9 @@ class SriovVIFDriver(neutron_vif.NeutronPodVIFDriver): if security_groups: port_req_body['security_groups'] = security_groups + if self._tag_on_creation: + tags = CONF.neutron_defaults.resource_tags + if tags: + port_req_body['tags'] = tags + return port_req_body diff --git a/kuryr_kubernetes/controller/drivers/utils.py b/kuryr_kubernetes/controller/drivers/utils.py index bcf0053d4..41c8ecf3f 100644 --- a/kuryr_kubernetes/controller/drivers/utils.py +++ b/kuryr_kubernetes/controller/drivers/utils.py @@ -208,6 +208,18 @@ def create_security_group_rule(body): raise +def check_tag_on_creation(): + """Checks if Neutron supports tagging during bulk port creation. + + :param os_net: Network proxy object from Openstacksdk. + :return: Boolean + """ + os_net = clients.get_network_client() + extension = os_net.find_extension( + name_or_id='tag-ports-during-bulk-creation') + return bool(extension) + + def delete_security_group_rule(security_group_rule_id): os_net = clients.get_network_client() try: diff --git a/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_macvlan_vif.py b/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_macvlan_vif.py index 04e578d1b..b7e3b22eb 100644 --- a/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_macvlan_vif.py +++ b/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_macvlan_vif.py @@ -32,6 +32,7 @@ class TestNestedMacvlanPodVIFDriver(test_base.TestCase): 'kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif_nested_macvlan') def test_request_vif(self, m_to_vif): cls = nested_macvlan_vif.NestedMacvlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -69,6 +70,7 @@ class TestNestedMacvlanPodVIFDriver(test_base.TestCase): 'kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif_nested_macvlan') def test_request_vif_port_create_failed(self, m_to_vif): cls = nested_macvlan_vif.NestedMacvlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -93,6 +95,7 @@ class TestNestedMacvlanPodVIFDriver(test_base.TestCase): 'kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif_nested_macvlan') def test_request_vif_parent_not_found(self, m_to_vif): cls = nested_macvlan_vif.NestedMacvlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client diff --git a/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_vlan_vif.py b/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_vlan_vif.py index 2782ebb83..e6b6a7fc8 100644 --- a/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_vlan_vif.py +++ b/kuryr_kubernetes/tests/unit/controller/drivers/test_nested_vlan_vif.py @@ -31,6 +31,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): 'kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif_nested_vlan') def test_request_vif(self, m_to_vif): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -75,6 +76,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): 'kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif_nested_vlan') def test_request_vifs(self, m_to_vif): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -124,6 +126,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): def test_request_vifs_no_vlans(self): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = False m_driver = mock.Mock(spec=cls) self.useFixture(k_fix.MockNetworkClient()).client @@ -155,6 +158,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): def test_request_vifs_bulk_creation_exception(self): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -195,6 +199,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): def test_request_vifs_trunk_subports_conflict(self): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -239,6 +244,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): def test_request_vifs_trunk_subports_exception(self): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = False m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -326,6 +332,7 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase): m_get_network_id, m_get_port_name, unbound=False): cls = nested_vlan_vif.NestedVlanPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) pod = mock.sentinel.pod diff --git a/kuryr_kubernetes/tests/unit/controller/drivers/test_neutron_vif.py b/kuryr_kubernetes/tests/unit/controller/drivers/test_neutron_vif.py index 33bb35813..13c3aa8df 100644 --- a/kuryr_kubernetes/tests/unit/controller/drivers/test_neutron_vif.py +++ b/kuryr_kubernetes/tests/unit/controller/drivers/test_neutron_vif.py @@ -33,6 +33,7 @@ class NeutronPodVIFDriver(test_base.TestCase): @mock.patch('kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif') def test_request_vif(self, m_to_vif): cls = neutron_vif.NeutronPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -61,6 +62,7 @@ class NeutronPodVIFDriver(test_base.TestCase): @mock.patch('kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif') def test_request_vifs(self, m_to_vif): cls = neutron_vif.NeutronPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -94,6 +96,7 @@ class NeutronPodVIFDriver(test_base.TestCase): @mock.patch('kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif') def test_request_vifs_unbound(self, m_to_vif): cls = neutron_vif.NeutronPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -131,6 +134,7 @@ class NeutronPodVIFDriver(test_base.TestCase): @mock.patch('kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif') def test_request_vifs_exception(self, m_to_vif): cls = neutron_vif.NeutronPodVIFDriver + cls._tag_on_creation = False m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client @@ -227,6 +231,7 @@ class NeutronPodVIFDriver(test_base.TestCase): m_get_device_id, m_get_port_name, m_get_host_id, m_get_network_id, unbound=False): cls = neutron_vif.NeutronPodVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) pod = mock.sentinel.pod @@ -259,6 +264,10 @@ class NeutronPodVIFDriver(test_base.TestCase): if security_groups: expected['security_groups'] = security_groups + tags = oslo_cfg.CONF.neutron_defaults.resource_tags + if cls._tag_on_creation and tags: + expected['tags'] = tags + if unbound: expected['name'] = constants.KURYR_PORT_NAME else: diff --git a/kuryr_kubernetes/tests/unit/controller/drivers/test_sriov.py b/kuryr_kubernetes/tests/unit/controller/drivers/test_sriov.py index abcf05386..8a26b0e0d 100644 --- a/kuryr_kubernetes/tests/unit/controller/drivers/test_sriov.py +++ b/kuryr_kubernetes/tests/unit/controller/drivers/test_sriov.py @@ -81,6 +81,7 @@ class TestSriovVIFDriver(test_base.TestCase): @mock.patch.object(ovu, 'neutron_to_osvif_vif') def test_request_vif(self, m_to_vif, m_to_fips): cls = drvs.SriovVIFDriver + cls._tag_on_creation = True m_driver = mock.Mock(spec=cls) os_net = self.useFixture(k_fix.MockNetworkClient()).client diff --git a/kuryr_kubernetes/tests/unit/controller/handlers/test_kuryrport.py b/kuryr_kubernetes/tests/unit/controller/handlers/test_kuryrport.py index d13f49f4c..a47c2d4ef 100644 --- a/kuryr_kubernetes/tests/unit/controller/handlers/test_kuryrport.py +++ b/kuryr_kubernetes/tests/unit/controller/handlers/test_kuryrport.py @@ -24,6 +24,7 @@ from kuryr_kubernetes.controller.drivers import multi_vif from kuryr_kubernetes.controller.handlers import kuryrport from kuryr_kubernetes import exceptions as k_exc from kuryr_kubernetes.tests import base as test_base +from kuryr_kubernetes.tests.unit import kuryr_fixtures as k_fix CONF = cfg.CONF @@ -87,6 +88,7 @@ class TestKuryrPortHandler(test_base.TestCase): self._pod_uri = (f"{constants.K8S_API_NAMESPACES}" f"/{self._kp['metadata']['namespace']}/pods/" f"{self._kp['metadata']['name']}") + self.useFixture(k_fix.MockNetworkClient()) self._driver = multi_vif.NoopMultiVIFDriver() @mock.patch('kuryr_kubernetes.controller.handlers.kuryrport.'