Add Neutron DHCP HA capabilities

Aiming for the stx-openstack application hardening, this change
implements the plugin logic to gather the number of available compute
nodes and, for anything that is not an AIO-SX deployment, configure the
neutron dhcp_agents_per_network count accordingly [1].
When only two computes are available this config is set to 2, whenever
three or more compute nodes are available this config is set to 3.

There are scenarios in which the compute node fails and if it is hosting
the DHCP agent for a given openstack network, VMs on that VM won't be
able to receive DHCPOFFER and fail to receive ip and ping.

Partial-Bug: 2030883

[1] https://docs.openstack.org/neutron/latest/admin/config-dhcp-ha.html#enabling-dhcp-high-availability-by-default

TEST PLAN:
PASS - Build plugins (k8sapp_openstack)
PASS - Build stx-openstack helm charts
PASS - Apply stx-openstack and verify the Neutron config
       * Check dhcp_agents_per_network count:
       /etc/neutron/neutron.conf
       - AIO-SX = 1
       - AIO-DX = 2
PASS - Execute stx-openstack sanity tests locally

Change-Id: I6f32ac8a1706467be0be67920a3a750bb7c6b01e
Signed-off-by: Thales Elero Cervi <thaleselero.cervi@windriver.com>
This commit is contained in:
Thales Elero Cervi 2023-12-13 20:44:04 -03:00
parent c593f29a84
commit 141f088a7e
1 changed files with 92 additions and 43 deletions

View File

@ -44,7 +44,6 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
self.interfaces_by_hostid = self._get_host_interfaces(
sort_key=self._interface_sort_key)
self.addresses_by_hostid = self._get_host_addresses()
host_overrides = self._get_per_host_overrides()
overrides = {
common.HELM_NS_OPENSTACK: {
@ -53,44 +52,12 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
'server': self._num_provisioned_controllers()
},
},
'conf': {
'plugins': {
'ml2_conf': self._get_neutron_ml2_config()
},
'overrides': {
'neutron_ovs-agent': {
'hosts': host_overrides
},
'neutron_dhcp-agent': {
'hosts': host_overrides
},
'neutron_l3-agent': {
'hosts': host_overrides
},
'neutron_metadata-agent': {
'hosts': host_overrides
},
'neutron_sriov-agent': {
'hosts': host_overrides
},
},
'paste': {
'app:neutronversions': {
'paste.app_factory':
'neutron.pecan_wsgi.app:versions_factory'
},
},
},
'conf': self._get_conf_overrides(),
'endpoints': self._get_endpoints_overrides(),
}
}
if self._is_openstack_https_ready():
overrides[common.HELM_NS_OPENSTACK] = self._update_overrides(
overrides[common.HELM_NS_OPENSTACK],
{'conf': self._get_conf_overrides()}
)
overrides[common.HELM_NS_OPENSTACK] = \
self._enable_certificates(overrides[common.HELM_NS_OPENSTACK])
@ -351,19 +318,101 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
def get_region_name(self):
return self._get_service_region_name(self.SERVICE_NAME)
def _is_ha(self):
"""
Determine if the system supports multiple deployments of
agents/services based on the number of available nodes.
"""
if utils.is_aio_simplex_system(self.dbapi):
return False
return True
def _get_ha_count(self):
"""
Determine the number of redundant deployments of
agents/services the system supports.
- AIO-SX supports only a single copy.
- AIO-DX supports two redundant copies.
- Any other deployment will be based on the number of
available compute nodes, fixing three as the maximum
value for redundant deployments.
:returns: the number of supported redundant deployments
"""
if not self._is_ha():
return 1
if utils.is_aio_duplex_system(self.dbapi):
return 2
compute_count = 0
hosts = self.dbapi.ihost_get_list()
for host in hosts:
host_labels = self.labels_by_hostid.get(host.id, [])
if (host.invprovision in [constants.PROVISIONED,
constants.PROVISIONING] or
host.ihost_action in [constants.UNLOCK_ACTION,
constants.FORCE_UNLOCK_ACTION]):
if (constants.WORKER in utils.get_personalities(host) and
utils.has_openstack_compute(host_labels)):
compute_count += 1
if compute_count >= 3:
return 3
else:
return compute_count
def _get_conf_overrides(self):
return {
host_overrides = self._get_per_host_overrides()
overrides = {
'neutron': {
'keystone_authtoken': {
'cafile': self.get_ca_file(),
'DEFAULT': {
'dhcp_agents_per_network': self._get_ha_count(),
}
},
'plugins': {
'ml2_conf': self._get_neutron_ml2_config()
},
'overrides': {
'neutron_ovs-agent': {
'hosts': host_overrides
},
'nova': {
'cafile': self.get_ca_file(),
'neutron_dhcp-agent': {
'hosts': host_overrides
},
'neutron_l3-agent': {
'hosts': host_overrides
},
'neutron_metadata-agent': {
'hosts': host_overrides
},
'neutron_sriov-agent': {
'hosts': host_overrides
},
},
'metadata_agent': {
'DEFAULT': {
'auth_ca_cert': self.get_ca_file(),
'paste': {
'app:neutronversions': {
'paste.app_factory':
'neutron.pecan_wsgi.app:versions_factory'
},
}
},
}
if self._is_openstack_https_ready():
overrides = self._update_overrides(overrides, {
'neutron': {
'keystone_authtoken': {
'cafile': self.get_ca_file(),
},
'nova': {
'cafile': self.get_ca_file(),
},
},
'metadata_agent': {
'DEFAULT': {
'auth_ca_cert': self.get_ca_file(),
},
}
})
return overrides