Add RPCAPI calls to apply LDAP client and DNS runtime manifest

This commit adds RPCAPI calls to invoke runtime manifest of LDAP
client and DNS after adding system controller network and system
controller OAM network in a subcloud after the initial network
configuration completed.

Tested:
Delete the system controller network and system controller OAM network
in a subcloud and add them with different values. The related
configuration and Hieradata are updated.

Depends-On: https://review.opendev.org/c/starlingx/stx-puppet/+/787750
Depends-On: https://review.opendev.org/c/starlingx/stx-puppet/+/785977
Story: 2008774
Task: 42307

Change-Id: I4ddf88efa16299c9415f4bf156f2be57e8cc826e
Signed-off-by: Yuxing Jiang <yuxing.jiang@windriver.com>
This commit is contained in:
Yuxing Jiang 2021-04-20 10:37:47 -04:00
parent 658d556fe9
commit b913052385
7 changed files with 164 additions and 0 deletions

View File

@ -345,8 +345,26 @@ class NetworkController(rest.RestController):
pecan.request.rpcapi.reconfigure_service_endpoints( pecan.request.rpcapi.reconfigure_service_endpoints(
pecan.request.context, chosts[0]) pecan.request.context, chosts[0])
# After the initial configration completed, we can still delete/add
# the system controller networks in a subcloud's controller to
# re-home a subcloud to a new central cloud. In this case, we want
# to update the related services configurations in runtime.
if cutils.is_initial_config_complete() and \
network['type'] in [constants.NETWORK_TYPE_SYSTEM_CONTROLLER,
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM]:
self._update_system_controller_network_config(network['type'])
return Network.convert_with_links(result) return Network.convert_with_links(result)
def _update_system_controller_network_config(self, type):
""" Update related services configurations after updating system
controller networks"""
if type == constants.NETWORK_TYPE_SYSTEM_CONTROLLER:
pecan.request.rpcapi.update_ldap_client_config(
pecan.request.context)
elif type == constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM:
pecan.request.rpcapi.update_dnsmasq_config(
pecan.request.context)
@wsme_pecan.wsexpose(NetworkCollection, @wsme_pecan.wsexpose(NetworkCollection,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc'): def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):

View File

@ -10733,6 +10733,26 @@ class ConductorManager(service.PeriodicService):
} }
self._config_apply_runtime_manifest(context, config_uuid, config_dict) self._config_apply_runtime_manifest(context, config_uuid, config_dict)
def update_dnsmasq_config(self, context):
"""Update the dnsmasq configuration"""
personalities = [constants.CONTROLLER]
config_uuid = self._config_update_hosts(context, personalities)
config_dict = {
"personalities": personalities,
"classes": ['platform::dns::dnsmasq::runtime'],
}
self._config_apply_runtime_manifest(context, config_uuid, config_dict)
def update_ldap_client_config(self, context):
"""Update the LDAP client configuration"""
personalities = [constants.CONTROLLER]
config_uuid = self._config_update_hosts(context, personalities)
config_dict = {
"personalities": personalities,
"classes": ['platform::ldap::client::runtime'],
}
self._config_apply_runtime_manifest(context, config_uuid, config_dict)
def get_ceph_pools_config(self, context): def get_ceph_pools_config(self, context):
return self._ceph.get_pools_config() return self._ceph.get_pools_config()

View File

@ -2186,3 +2186,25 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
:param context: request context. :param context: request context.
""" """
return self.call(context, self.make_msg('get_restore_state')) return self.call(context, self.make_msg('get_restore_state'))
def update_ldap_client_config(self, context):
"""Synchronously, have a conductor configure LDAP client configureation
Does the following tasks:
- Update puppet hiera configuration file and apply run time manifest.
:param context: request context.
"""
return self.call(context,
self.make_msg('update_ldap_client_config'))
def update_dnsmasq_config(self, context):
"""Synchronously, have a conductor configure the DNS configuration
Does the following tasks:
- Update puppet hiera configuration file and apply run time manifest.
:param context: request context.
"""
return self.call(context,
self.make_msg('update_dnsmasq_config'))

View File

@ -120,6 +120,14 @@ class NetworkTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
hostnames, self.storage_subnet, hostnames, self.storage_subnet,
constants.NETWORK_TYPE_STORAGE) constants.NETWORK_TYPE_STORAGE)
self._create_test_addresses(
hostnames, self.system_controller_subnet,
constants.NETWORK_TYPE_SYSTEM_CONTROLLER)
self._create_test_addresses(
hostnames, self.system_controller_oam_subnet,
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM)
class TestPostMixin(NetworkTestCase): class TestPostMixin(NetworkTestCase):
@ -175,6 +183,38 @@ class TestPostMixin(NetworkTestCase):
self.assertIn("Network of type %s already exists." % network_type, self.assertIn("Network of type %s already exists." % network_type,
response.json['error_message']) response.json['error_message'])
def test_create_success_system_controller_oam(self):
self._create_test_host(constants.CONTROLLER)
m = mock.Mock()
update_dnsmasq_config = "sysinv.conductor.rpcapi." \
"ConductorAPI." \
"update_dnsmasq_config"
with mock.patch('sysinv.common.utils.is_initial_config_complete',
lambda: True), \
mock.patch(update_dnsmasq_config,
m.update_dnsmasq_config):
self._test_create_network_success(
'system-controller-oam',
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM,
self.system_controller_oam_subnet)
m.update_dnsmasq_config.assert_called_once()
def test_create_success_system_controller(self):
self._create_test_host(constants.CONTROLLER)
m = mock.Mock()
update_ldap_client_config = "sysinv.conductor.rpcapi." \
"ConductorAPI." \
"update_ldap_client_config"
with mock.patch('sysinv.common.utils.is_initial_config_complete',
lambda: True), \
mock.patch(update_ldap_client_config,
m.update_ldap_client_config):
self._test_create_network_success(
'system-controller',
constants.NETWORK_TYPE_SYSTEM_CONTROLLER,
self.system_controller_subnet)
m.update_ldap_client_config.assert_called_once()
def test_create_success_pxeboot(self): def test_create_success_pxeboot(self):
self._test_create_network_success( self._test_create_network_success(
'pxeboot', 'pxeboot',

View File

@ -1901,6 +1901,44 @@ class ManagerTestCase(base.DbTestCase):
ihost = self.dbapi.ihost_get(host_id) ihost = self.dbapi.ihost_get(host_id)
self.assertEqual(ihost.reboot_needed, True) self.assertEqual(ihost.reboot_needed, True)
def test_update_dnsmasq_config(self):
mock_config_update_hosts = mock.MagicMock()
mock_config_apply_runtime_manifest = mock.MagicMock()
p = mock.patch('sysinv.conductor.manager.ConductorManager._config_update_hosts',
mock_config_update_hosts)
p.start().return_value = '1234'
self.addCleanup(p.stop)
p2 = mock.patch('sysinv.conductor.manager.ConductorManager._config_apply_runtime_manifest',
mock_config_apply_runtime_manifest)
p2.start()
self.addCleanup(p2.stop)
self.service.update_dnsmasq_config(self.context)
personalities = [constants.CONTROLLER]
config_dict = {
"personalities": personalities,
"classes": ['platform::dns::dnsmasq::runtime'],
}
mock_config_apply_runtime_manifest.assert_called_with(mock.ANY, '1234', config_dict)
def test_update_ldap_client_config(self):
mock_config_update_hosts = mock.MagicMock()
mock_config_apply_runtime_manifest = mock.MagicMock()
p = mock.patch('sysinv.conductor.manager.ConductorManager._config_update_hosts',
mock_config_update_hosts)
p.start().return_value = '1234'
self.addCleanup(p.stop)
p2 = mock.patch('sysinv.conductor.manager.ConductorManager._config_apply_runtime_manifest',
mock_config_apply_runtime_manifest)
p2.start()
self.addCleanup(p2.stop)
self.service.update_ldap_client_config(self.context)
personalities = [constants.CONTROLLER]
config_dict = {
"personalities": personalities,
"classes": ['platform::ldap::client::runtime'],
}
mock_config_apply_runtime_manifest.assert_called_with(mock.ANY, '1234', config_dict)
class ManagerTestCaseInternal(base.BaseHostTestCase): class ManagerTestCaseInternal(base.BaseHostTestCase):

View File

@ -95,3 +95,9 @@ class RPCAPITestCase(base.DbTestCase):
'call', 'call',
host=self.fake_ihost, host=self.fake_ihost,
do_worker_apply=False) do_worker_apply=False)
def test_update_ldap_client_config(self):
self._test_rpcapi('update_ldap_client_config', 'call')
def test_update_dnsmasq_config(self):
self._test_rpcapi('update_dnsmasq_config', 'call')

View File

@ -48,6 +48,8 @@ class BaseIPv4Mixin(object):
cluster_service_subnet = netaddr.IPNetwork('10.96.0.0/12') cluster_service_subnet = netaddr.IPNetwork('10.96.0.0/12')
multicast_subnet = netaddr.IPNetwork('239.1.1.0/28') multicast_subnet = netaddr.IPNetwork('239.1.1.0/28')
storage_subnet = netaddr.IPNetwork('10.10.20.0/24') storage_subnet = netaddr.IPNetwork('10.10.20.0/24')
system_controller_subnet = netaddr.IPNetwork('192.168.104.0/24')
system_controller_oam_subnet = netaddr.IPNetwork('10.10.50.0/24')
nameservers = ['8.8.8.8', '8.8.4.4'] nameservers = ['8.8.8.8', '8.8.4.4']
@ -65,6 +67,8 @@ class BaseIPv6Mixin(object):
cluster_service_subnet = netaddr.IPNetwork('fd04::/112') cluster_service_subnet = netaddr.IPNetwork('fd04::/112')
multicast_subnet = netaddr.IPNetwork('ff08::1:1:0/124') multicast_subnet = netaddr.IPNetwork('ff08::1:1:0/124')
storage_subnet = netaddr.IPNetwork('fd05::/64') storage_subnet = netaddr.IPNetwork('fd05::/64')
system_controller_subnet = netaddr.IPNetwork('fd07::/64')
system_controller_oam_subnet = netaddr.IPNetwork('fd06::/64')
nameservers = ['2001:4860:4860::8888', '2001:4860:4860::8844'] nameservers = ['2001:4860:4860::8888', '2001:4860:4860::8844']
@ -240,6 +244,14 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_STORAGE,
self.storage_subnet) self.storage_subnet)
self._create_test_network('system-controller',
constants.NETWORK_TYPE_SYSTEM_CONTROLLER,
self.system_controller_subnet)
self._create_test_network('system-controller-oam',
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM,
self.system_controller_oam_subnet)
def _create_test_addresses(self, hostnames, subnet, network_type, def _create_test_addresses(self, hostnames, subnet, network_type,
start=1, stop=None): start=1, stop=None):
ips = itertools.islice(subnet, start, stop) ips = itertools.islice(subnet, start, stop)
@ -286,6 +298,14 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
hostnames, self.storage_subnet, hostnames, self.storage_subnet,
constants.NETWORK_TYPE_STORAGE) constants.NETWORK_TYPE_STORAGE)
self._create_test_addresses(
hostnames, self.system_controller_subnet,
constants.NETWORK_TYPE_SYSTEM_CONTROLLER)
self._create_test_addresses(
hostnames, self.system_controller_oam_subnet,
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM)
def _create_test_oam(self): def _create_test_oam(self):
self.oam = dbutils.create_test_oam() self.oam = dbutils.create_test_oam()