From f6158f5b02124871c74f23c12228b533db7132af Mon Sep 17 00:00:00 2001 From: Caio Bruchert Date: Mon, 1 Apr 2024 16:59:08 -0300 Subject: [PATCH] Prevent multiple datanetworks to same interface Since sriov-network-device-plugin upgrade to v3.5.1, assigning multiple datanetworks to the same interface is not possible anymore. This change restricts the system interface-datanetwork-assign command to prevent that from happening. Test Plan: PASS: assign datanetwork1 to sriov0 interface: ok PASS: assign datanetwork2 to same sriov0 interface: fails PASS: create new vf0 interface on top of sriov0: ok PASS: assign datanetwork1 to vf0: ok PASS: assign datanetwork2 to vf0: fails PASS: create new vf1 interface on top of sriov0: ok PASS: assign datanetwork2 to vf1: ok PASS: assign datanetwork1 to vf1: fails Closes-Bug: 2059960 Change-Id: If3ab95594917089f01475f9595c9059edeae85f5 Signed-off-by: Caio Bruchert --- .../controllers/v1/interface_datanetwork.py | 14 ++++---- .../tests/api/test_interface_datanetwork.py | 34 +++++++++++++------ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_datanetwork.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_datanetwork.py index 79f2239225..046f065682 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_datanetwork.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_datanetwork.py @@ -17,7 +17,7 @@ # under the License. # # -# Copyright (c) 2019 Wind River Systems, Inc. +# Copyright (c) 2019-2024 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -244,20 +244,20 @@ class InterfaceDataNetworkController(rest.RestController): @staticmethod def _query_interface_datanetwork(interface_datanetwork): try: - result = pecan.request.dbapi.interface_datanetwork_query( - interface_datanetwork) + result = pecan.request.dbapi.interface_datanetwork_get_by_interface( + interface_datanetwork['interface_id'], 1) except exception.InterfaceDataNetworkNotFoundByKeys: return None - return result + return result[0] if len(result) > 0 else None def _check_duplicate_interface_datanetwork(self, interface_datanetwork): ifdn = self._query_interface_datanetwork(interface_datanetwork) if not ifdn: return - msg = _("Interface '%s' assignment with Data Network '%s' " - "already exists." + msg = _("Interface '%s' can have only one Data Network assignment." + " Data Network '%s' already assigned." % (ifdn['ifname'], - ifdn['datanetwork_name'])) + ifdn['datanetwork_name'])) raise wsme.exc.ClientSideError(msg) @staticmethod diff --git a/sysinv/sysinv/sysinv/sysinv/tests/api/test_interface_datanetwork.py b/sysinv/sysinv/sysinv/sysinv/tests/api/test_interface_datanetwork.py index ac4f39c807..141ac3de30 100644 --- a/sysinv/sysinv/sysinv/sysinv/tests/api/test_interface_datanetwork.py +++ b/sysinv/sysinv/sysinv/sysinv/tests/api/test_interface_datanetwork.py @@ -2,7 +2,7 @@ # -*- encoding: utf-8 -*- # # -# Copyright (c) 2021 Wind River Systems, Inc. +# Copyright (c) 2021-2024 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -44,8 +44,13 @@ class InterfaceDataNetworkTestCase(base.FunctionalTest): administrative=constants.ADMIN_UNLOCKED, invprovision=constants.PROVISIONED, ) - self.datanetwork = dbutils.create_test_datanetwork( - name='test1', + self.datanetwork0 = dbutils.create_test_datanetwork( + name='dn0', + uuid=str(uuid.uuid4()), + network_type=constants.DATANETWORK_TYPE_VLAN, + mtu=1500) + self.datanetwork1 = dbutils.create_test_datanetwork( + name='dn1', uuid=str(uuid.uuid4()), network_type=constants.DATANETWORK_TYPE_VLAN, mtu=1500) @@ -88,39 +93,48 @@ class InterfaceDataNetworkCreateTestCase(InterfaceDataNetworkTestCase): super(InterfaceDataNetworkCreateTestCase, self).setUp() def test_assign_interface_datanetwork(self): - # system interface-datanetwork-assign controller-0 sriov0 test1 + # system interface-datanetwork-assign controller-0 sriov0 dn0 sriov0_assign_dn = dbutils.post_get_test_interface_datanetwork( interface_uuid=self.if_sriov0.uuid, - datanetwork_uuid=self.datanetwork.uuid) + datanetwork_uuid=self.datanetwork0.uuid) self._post_and_check(sriov0_assign_dn, expect_errors=False) # system interface-datanetwork-list controller-0 if_dn_list = self.get_json('/ihosts/%s/interface_datanetworks' % self.controller.uuid, expect_errors=False) - self.assertEqual('test1', if_dn_list['interface_datanetworks'][0]['datanetwork_name']) + self.assertEqual('dn0', if_dn_list['interface_datanetworks'][0]['datanetwork_name']) self.assertEqual('sriov0', if_dn_list['interface_datanetworks'][0]['ifname']) + # Assign the same data network again + self._post_and_check(sriov0_assign_dn, expect_errors=True) + + # Assign a different data network to the same interface + sriov0_assign_dn1 = dbutils.post_get_test_interface_datanetwork( + interface_uuid=self.if_sriov0.uuid, + datanetwork_uuid=self.datanetwork1.uuid) + self._post_and_check(sriov0_assign_dn1, expect_errors=True) + # system interface-datanetwork-remove {uuid} self.delete('/interface_datanetworks/%s' % if_dn_list['interface_datanetworks'][0]['uuid'], expect_errors=False) def test_assign_interface_datanetwork_error_non_sriov(self): - # system interface-datanetwork-assign controller-0 data0 test1 + # system interface-datanetwork-assign controller-0 data0 dn0 # rejected because host is unlocked data0_assign_dn = dbutils.post_get_test_interface_datanetwork( interface_uuid=self.if_data0.uuid, - datanetwork_uuid=self.datanetwork.uuid) + datanetwork_uuid=self.datanetwork0.uuid) self._post_and_check(data0_assign_dn, expect_errors=True) def test_assign_interface_datanetwork_error_non_aio_sx(self): self.mock_utils_is_aio_simplex_system.return_value = False - # system interface-datanetwork-assign controller-0 sriov1 test1 + # system interface-datanetwork-assign controller-0 sriov1 dn0 # rejected because system is not AIO-SX sriov1_assign_dn = dbutils.post_get_test_interface_datanetwork( interface_uuid=self.if_sriov1.uuid, - datanetwork_uuid=self.datanetwork.uuid) + datanetwork_uuid=self.datanetwork0.uuid) self._post_and_check(sriov1_assign_dn, expect_errors=True) self.mock_utils_is_aio_simplex_system.return_value = True