Check vswitch type to deploy daemonsets for Neutron L3 agents
Neutron L3 agent daemonsets are only required if openvswitch is enabled. However, currently, even when openvswitch is not used the L3 agent daemonsets are being created, but never deployed. This increases the k8s memory consumption and affects the platform scalability (number of compute nodes supported). This change enables the deployment of Neutron L3 agent daemonsets only when openvswitch is enabled. Test Plan: PASS: build-pkg -c -l openstack PASS: build openstack tarball PASS: Upload and Apply openstack tarball on standard system PASS: Check that Neutron L3 agents are not deployed PASS: Check size reduction in Neutron release secret PASS: Launch 3x Guest instances (centos-guest VMs) PASS: Access instances through a remote console PASS: Ping instances from remote console (all to all) PASS: Ping instances from external server in the management network Story: 2011304 Task: 51504 Change-Id: If22f63cf893d547e1e31da71ddb512622a25662c Signed-off-by: Ingo Almendros Girao <ingo.almendrosgirao@windriver.com> Co-authored-by: Alex Figueiredo <alex.fernandesfigueiredo@windriver.com>
This commit is contained in:
committed by
Ingo Girao
co-authored by
Alex Figueiredo
parent
42cbe2261a
commit
c19b2bd5ad
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2019-2024 Wind River Systems, Inc.
|
||||
# Copyright (c) 2019-2025 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@@ -12,6 +12,7 @@ from sysinv.helm import common
|
||||
|
||||
from k8sapp_openstack.common import constants as app_constants
|
||||
from k8sapp_openstack.helm import openstack
|
||||
from k8sapp_openstack.utils import is_openvswitch_enabled
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@@ -53,6 +54,7 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
|
||||
},
|
||||
},
|
||||
'conf': self._get_conf_overrides(),
|
||||
'manifests': self._get_manifests_overrides(),
|
||||
'endpoints': self._get_endpoints_overrides(),
|
||||
}
|
||||
}
|
||||
@@ -439,3 +441,10 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
|
||||
})
|
||||
|
||||
return overrides
|
||||
|
||||
def _get_manifests_overrides(self):
|
||||
manifests_overrides = {}
|
||||
hosts = self.dbapi.ihost_get_list()
|
||||
openvswitch_enabled = is_openvswitch_enabled(hosts, self.labels_by_hostid)
|
||||
manifests_overrides.update({'daemonset_l3_agent': openvswitch_enabled})
|
||||
return manifests_overrides
|
||||
|
||||
+32
-1
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2020-2024 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2025 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@@ -20,6 +20,9 @@ class NeutronHelmTestCase(test_plugins.K8SAppOpenstackAppMixin,
|
||||
def setUp(self):
|
||||
super(NeutronHelmTestCase, self).setUp()
|
||||
self.app = dbutils.create_test_app(name=self.app_name)
|
||||
self.app.dbapi = mock.MagicMock()
|
||||
self.neutron_helm = neutron.NeutronHelm(self.app.dbapi)
|
||||
self.neutron_helm.labels_by_hostid = {}
|
||||
|
||||
|
||||
class NeutronGetOverrideTest(NeutronHelmTestCase,
|
||||
@@ -133,3 +136,31 @@ class NeutronGetOverrideTest(NeutronHelmTestCase,
|
||||
'certificates': True,
|
||||
},
|
||||
})
|
||||
|
||||
@mock.patch('k8sapp_openstack.helm.neutron.is_openvswitch_enabled',
|
||||
return_value=True)
|
||||
def test_get_manifests_overrides_openvswitch_enabled(self, mock_is_openvswitch_enabled):
|
||||
"""
|
||||
Test for the _get_manifests_overrides function to ensure the correct
|
||||
'daemonset_l3_agent' value is returned based on the openvswitch status.
|
||||
"""
|
||||
self.app.dbapi.ihost_get_list.return_value = [
|
||||
mock.MagicMock(id=1),
|
||||
mock.MagicMock(id=2)
|
||||
]
|
||||
overrides = self.neutron_helm._get_manifests_overrides()
|
||||
self.assertEqual({'daemonset_l3_agent': True}, overrides)
|
||||
|
||||
@mock.patch('k8sapp_openstack.helm.neutron.is_openvswitch_enabled',
|
||||
return_value=False)
|
||||
def test_get_manifests_overrides_openvswitch_disabled(self, mock_is_openvswitch_enabled):
|
||||
"""
|
||||
Test for the _get_manifests_overrides function to ensure the correct
|
||||
'daemonset_l3_agent' value is returned based on the openvswitch status.
|
||||
"""
|
||||
self.app.dbapi.ihost_get_list.return_value = [
|
||||
mock.MagicMock(id=1),
|
||||
mock.MagicMock(id=2)
|
||||
]
|
||||
overrides = self.neutron_helm._get_manifests_overrides()
|
||||
self.assertEqual({'daemonset_l3_agent': False}, overrides)
|
||||
|
||||
+52
-1
@@ -1,10 +1,12 @@
|
||||
#
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2022-2025 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import mock
|
||||
from sysinv.common import constants
|
||||
from sysinv.helm import common as helm_common
|
||||
from sysinv.tests.db import base as dbbase
|
||||
|
||||
from k8sapp_openstack import utils as app_utils
|
||||
@@ -21,3 +23,52 @@ class UtilsTest(dbbase.ControllerHostTestCase):
|
||||
@mock.patch('k8sapp_openstack.utils.is_openstack_https_ready', return_value=False)
|
||||
def test_is_openstack_https_ready_false(self, *_):
|
||||
self.assertFalse(app_utils.is_openstack_https_ready())
|
||||
|
||||
def test_is_openvswitch_enabled_true(self):
|
||||
"""Test is_openvswitch_enabled returns True when openvswitch
|
||||
is enabled.
|
||||
"""
|
||||
mock_host = mock.MagicMock()
|
||||
mock_host.id = 1
|
||||
mock_host.invprovision = constants.PROVISIONED
|
||||
mock_host.ihost_action = constants.UNLOCK_ACTION
|
||||
mock_label = mock.MagicMock()
|
||||
mock_label.label_key = helm_common.LABEL_OPENVSWITCH
|
||||
mock_label.label_value = helm_common.LABEL_VALUE_ENABLED
|
||||
|
||||
hosts = [mock_host]
|
||||
labels_by_hostid = {
|
||||
mock_host.id: [mock_label]
|
||||
}
|
||||
|
||||
with mock.patch('k8sapp_openstack.utils.cutils.get_personalities',
|
||||
return_value=[constants.WORKER]), \
|
||||
mock.patch('k8sapp_openstack.utils.cutils.has_openstack_compute',
|
||||
return_value=True):
|
||||
result = app_utils.is_openvswitch_enabled(hosts, labels_by_hostid)
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_is_openvswitch_enabled_false(self):
|
||||
"""Test is_openvswitch_enabled returns False when openvswitch
|
||||
is not enabled.
|
||||
"""
|
||||
mock_host = mock.MagicMock()
|
||||
mock_host.id = 1
|
||||
mock_host.invprovision = constants.PROVISIONED
|
||||
mock_host.ihost_action = constants.UNLOCK_ACTION
|
||||
|
||||
mock_label = mock.MagicMock()
|
||||
mock_label.label_key = "fake_label"
|
||||
mock_label.label_value = "fake_value"
|
||||
|
||||
hosts = [mock_host]
|
||||
labels_by_hostid = {
|
||||
mock_host.id: [mock_label]
|
||||
}
|
||||
|
||||
with mock.patch('k8sapp_openstack.utils.cutils.get_personalities',
|
||||
return_value=[constants.WORKER]), \
|
||||
mock.patch('k8sapp_openstack.utils.cutils.has_openstack_compute',
|
||||
return_value=True):
|
||||
result = app_utils.is_openvswitch_enabled(hosts, labels_by_hostid)
|
||||
self.assertFalse(result)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2023-2024 Wind River Systems, Inc.
|
||||
# Copyright (c) 2023-2025 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@@ -20,6 +20,7 @@ from sysinv.common import constants
|
||||
from sysinv.common import kubernetes
|
||||
from sysinv.common import utils as cutils
|
||||
from sysinv.db import api as dbapi
|
||||
from sysinv.helm import common as helm_common
|
||||
import yaml
|
||||
|
||||
from k8sapp_openstack.common import constants as app_constants
|
||||
@@ -538,3 +539,36 @@ def is_netapp_available() -> bool:
|
||||
"""
|
||||
netapp_backends = check_netapp_backends()
|
||||
return netapp_backends["nfs"] or netapp_backends["iscsi"]
|
||||
|
||||
|
||||
def is_openvswitch_enabled(hosts, labels_by_hostid) -> bool:
|
||||
"""
|
||||
Check if openvswitch is enabled.
|
||||
|
||||
Args:
|
||||
hosts (list): A list of hosts registered in the database.
|
||||
labels_by_hostid (dict): A dictionary of labels associated
|
||||
with a specific host ID.
|
||||
|
||||
Returns:
|
||||
bool: True if openvswitch is enabled or False if it is not.
|
||||
"""
|
||||
for host in hosts:
|
||||
host_labels = labels_by_hostid.get(host.id, [])
|
||||
if not host_labels:
|
||||
LOG.debug(f"No labels found for host ID {host.id}")
|
||||
labels = dict((label.label_key, label.label_value) for label in host_labels)
|
||||
if (host.invprovision in [constants.PROVISIONED,
|
||||
constants.PROVISIONING] or
|
||||
host.ihost_action in [constants.UNLOCK_ACTION,
|
||||
constants.FORCE_UNLOCK_ACTION]):
|
||||
if (constants.WORKER in cutils.get_personalities(host) and
|
||||
cutils.has_openstack_compute(host_labels)):
|
||||
if (helm_common.LABEL_OPENVSWITCH in labels):
|
||||
vswitch_label_value = labels.get(helm_common.LABEL_OPENVSWITCH)
|
||||
LOG.debug(f"Open vSwitch label value for host {host.id}: {vswitch_label_value}")
|
||||
return helm_common.LABEL_VALUE_ENABLED == vswitch_label_value.lower()
|
||||
else:
|
||||
LOG.debug(f"Openvswitch label not found for host {host.id}")
|
||||
LOG.info("Openvswitch is not enabled on any of the hosts.")
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user