Dual-stack: ceph matches address name and family

This change splits the IP service for each platform network into ipv4
and ipv6 to support dual-stack. It still supports single-stack (when
there is only ipv4 or ipv6). Each service is instantiated if there is
a configuration for it.

Ceph was not taking into account the address family to generate the
list of IPs using the primary pool. This lead to a wrong puppet
variable content.

Test Plan:
[PASS] install, lock, unlock and swact for the following setups
       - AIO-SX (IPv4 and IPv6)
       - AIO-DX (IPv4 and IPv6)
       - Standard (IPv4 and IPv6)
       - DC (SisCtrl=AIO-DX, subcloud=AIO-SX)
[PASS] Add dual-stack configuration and validate services operation
       with lock, unlock and swact:
       - AIO-SX (IPv4 and IPv6)
       - AIO-DX (IPv4 and IPv6)
       - Standard (IPv4 and IPv6)
       - DC (SisCtrl=AIO-DX, subcloud=AIO-SX), using the admin network

Story: 2011027
Task: 49763

Change-Id: Icda298c51cdd2535146b1e11669f1c6f64c232b7
Signed-off-by: Andre Kantek <andrefernandozanella.kantek@windriver.com>
This commit is contained in:
Andre Kantek 2024-03-21 09:03:24 -03:00
parent 78b3fe851f
commit 4459b82f32
2 changed files with 90 additions and 4 deletions

View File

@ -1,7 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (c) 2016-2022 Wind River Systems, Inc.
# Copyright (c) 2016-2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -223,9 +223,11 @@ class StorageBackendConfig(object):
hostif = '%s-%s' % (host, network_type)
hostif2ph[hostif] = ph
# map placeholder to ceph-mon ip address
network = dbapi.network_get_by_type(network_type)
addr_pool = dbapi.address_pool_get(network.pool_uuid)
ph2ipaddr = OrderedDict({})
for addr in dbapi.addresses_get_all():
if addr.name in hostif2ph:
if (addr.name in hostif2ph) and (addr.family == addr_pool.family):
ph = hostif2ph[addr.name]
ph2ipaddr[ph] = addr.address
return ph2ipaddr

View File

@ -2,7 +2,7 @@
# -*- encoding: utf-8 -*-
#
#
# Copyright (c) 2017-2021 Wind River Systems, Inc.
# Copyright (c) 2017-2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -1379,6 +1379,26 @@ class StorageBackendConfigTest(base.FunctionalTest):
super(StorageBackendConfigTest, self).setUp()
self.dbapi = dbapi.get_instance()
pool_mgmt = dbutils.create_test_address_pool(
name='mgmt',
network='192.168.204.0',
ranges=[['192.168.204.2', '192.168.204.254']],
prefix=24)
dbutils.create_test_network(
type=constants.NETWORK_TYPE_MGMT,
address_pool_id=pool_mgmt.id,
primary_pool_family="IPv4")
pool_clhost = dbutils.create_test_address_pool(
name='clhost',
network='193.168.204.0',
ranges=[['193.168.204.2', '193.168.204.254']],
prefix=24)
dbutils.create_test_network(
type=constants.NETWORK_TYPE_CLUSTER_HOST,
address_pool_id=pool_clhost.id,
primary_pool_family="IPv4")
def test_get_ceph_mon_ip_addresses(self):
self._test_get_ceph_mon_ip_addresses(constants.NETWORK_TYPE_MGMT)
self._test_get_ceph_mon_ip_addresses(constants.NETWORK_TYPE_CLUSTER_HOST)
@ -1396,7 +1416,71 @@ class StorageBackendConfigTest(base.FunctionalTest):
addresses = list(map(lambda x: '{}-{}'.format(x, network_type), hostnames))
addresses_mock = \
list(map(lambda x, y: ({'name': x, 'address': y}), addresses, ips_mock))
list(map(lambda x, y: ({'name': x, 'address': y,
'family': constants.IPV4_FAMILY}), addresses, ips_mock))
addresses_mock_object = \
list(map(lambda x: namedtuple("Addresses", x.keys())(*x.values()), addresses_mock))
p = mock.patch.object(self.dbapi, 'ceph_mon_get_list')
p.start().return_value = list(map(lambda x: {'hostname': x}, hostnames))
self.addCleanup(p.stop)
p = mock.patch.object(self.dbapi, 'storage_ceph_get_list')
p.start().return_value = [{'network': network_type}]
self.addCleanup(p.stop)
p = mock.patch.object(self.dbapi, 'addresses_get_all')
p.start().return_value = addresses_mock_object
self.addCleanup(p.stop)
result = StorageBackendConfig.get_ceph_mon_ip_addresses(self.dbapi)
self.assertDictEqual(result, result_mock)
class StorageBackendConfigTestIPv6(base.FunctionalTest):
def setUp(self):
super(StorageBackendConfigTestIPv6, self).setUp()
self.dbapi = dbapi.get_instance()
pool_mgmt = dbutils.create_test_address_pool(
name='mgmt-ipv6',
network='fd00::',
ranges=[['fd00::1', 'fd00::ffff']],
prefix=64, family=constants.IPV6_FAMILY)
dbutils.create_test_network(
type=constants.NETWORK_TYPE_MGMT,
address_pool_id=pool_mgmt.id,
primary_pool_family="IPv6")
pool_clhost = dbutils.create_test_address_pool(
name='clhost-ipv6',
network='fd01::',
ranges=[['fd01::1', 'fd00::ffff']],
prefix=64, family=constants.IPV6_FAMILY)
dbutils.create_test_network(
type=constants.NETWORK_TYPE_CLUSTER_HOST,
address_pool_id=pool_clhost.id,
primary_pool_family="IPv6")
def test_get_ceph_mon_ipv6_addresses(self):
self._test_get_ceph_mon_ip_addresses(constants.NETWORK_TYPE_MGMT)
self._test_get_ceph_mon_ip_addresses(constants.NETWORK_TYPE_CLUSTER_HOST)
pass
def _test_get_ceph_mon_ip_addresses(self, network_type):
hostnames = [constants.CONTROLLER_HOSTNAME,
constants.CONTROLLER_0_HOSTNAME,
constants.CONTROLLER_1_HOSTNAME]
ips_mock = ['1', '2', '3']
placeholders = [constants.CEPH_FLOATING_MON,
constants.CEPH_MON_0,
constants.CEPH_MON_1]
result_mock = dict(map(lambda x, y: (x, y), placeholders, ips_mock))
addresses = list(map(lambda x: '{}-{}'.format(x, network_type), hostnames))
addresses_mock = \
list(map(lambda x, y: ({'name': x, 'address': y,
'family': constants.IPV6_FAMILY}), addresses, ips_mock))
addresses_mock_object = \
list(map(lambda x: namedtuple("Addresses", x.keys())(*x.values()), addresses_mock))