Refactor network reconfiguration during reinstall

With this commit, we can now reconfigure the network with any
changes in network values during reinstall. Previously, only
the subnet was verified. Additionally, we've added a check to
ensure that the subnet remains the same after the reconfiguration
to prevent accidental route deletion.

Test Plan:
1. Perform a subcloud install
2. Perform a subcloud reinstall
- Using a different subnet value
- Using the same subnet but different start address
- Using the same network values

Story: 2010319
Task: 48437

Change-Id: I55edf5309f6d1ffcd4f64240b39e26110bf9aacc
Signed-off-by: Hugo Brito <hugo.brito@windriver.com>
This commit is contained in:
Hugo Brito
2023-07-18 14:38:26 -03:00
committed by Hugo Nicodemos
parent 6eb4a6d2dc
commit eda6e319e3
5 changed files with 117 additions and 8 deletions

View File

@@ -921,6 +921,27 @@ def get_management_gateway_address(payload):
return payload.get('management_gateway_address', '')
def has_network_reconfig(payload, subcloud):
"""Check if network reconfiguration is needed
:param payload: subcloud configuration
:param subcloud: subcloud object
"""
management_subnet = get_management_subnet(payload)
start_address = get_management_start_address(payload)
end_address = get_management_end_address(payload)
gateway_address = get_management_gateway_address(payload)
has_network_reconfig = any([
management_subnet != subcloud.management_subnet,
start_address != subcloud.management_start_ip,
end_address != subcloud.management_end_ip,
gateway_address != subcloud.management_gateway_ip
])
return has_network_reconfig
def set_open_file_limit(new_soft_limit: int):
"""Adjust the maximum number of open files for this process (soft limit)"""
try:

View File

@@ -30,7 +30,6 @@ from cgtsclient.exc import HTTPConflict
from eventlet import greenpool
from fm_api import constants as fm_const
from fm_api import fm_api
import ipaddress
import keyring
import netaddr
from oslo_log import log as logging
@@ -626,8 +625,7 @@ class SubcloudManager(manager.Manager):
subcloud.name,
ansible_subcloud_inventory_file,
payload['software_version'])
management_subnet = utils.get_management_subnet(payload)
network_reconfig = management_subnet != subcloud.management_subnet
network_reconfig = utils.has_network_reconfig(payload, subcloud)
apply_thread = threading.Thread(
target=self.run_deploy_thread,
args=(subcloud, payload, context,
@@ -2326,6 +2324,7 @@ class SubcloudManager(manager.Manager):
def _configure_system_controller_network(self, context, payload, subcloud):
subcloud_name = subcloud.name
subcloud_id = subcloud.id
try:
m_ks_client = OpenStackDriver(
region_name=dccommon_consts.DEFAULT_REGION_NAME,
@@ -2334,8 +2333,7 @@ class SubcloudManager(manager.Manager):
subcloud.systemcontroller_gateway_ip)
except HTTPConflict:
# The route already exists
LOG.warning(
"Failed to create route to subcloud %s" % subcloud_name)
LOG.warning("Failed to create route to subcloud %s" % subcloud_name)
except Exception:
LOG.exception(
"Failed to create route to subcloud %s." % subcloud_name)
@@ -2358,7 +2356,8 @@ class SubcloudManager(manager.Manager):
return
# Delete old routes
self._delete_subcloud_routes(m_ks_client, subcloud)
if utils.get_management_subnet(payload) != subcloud.management_subnet:
self._delete_subcloud_routes(m_ks_client, subcloud)
def _create_subcloud_route(self, payload, keystone_client,
systemcontroller_gateway_ip):
@@ -2378,8 +2377,7 @@ class SubcloudManager(manager.Manager):
def _update_services_endpoint(
self, context, payload, subcloud_name, m_ks_client):
endpoint_ip = str(ipaddress.ip_network(
utils.get_management_subnet(payload))[2])
endpoint_ip = utils.get_management_start_address(payload)
if netaddr.IPAddress(endpoint_ip).version == 6:
endpoint_ip = f"[{endpoint_ip}]"
@@ -2409,6 +2407,9 @@ class SubcloudManager(manager.Manager):
LOG.exception("Endpoint Type Error: %s" % service_type)
m_ks_client.keystone_client.endpoints.update(
endpoint, url=admin_endpoint_url)
LOG.info("Update services endpoint to %s in subcloud %s" % (
endpoint_ip, subcloud_name))
# Update service URLs in subcloud endpoint cache
self.audit_rpc_client.trigger_subcloud_endpoints_update(
context, subcloud_name, services_endpoints)

View File

@@ -912,6 +912,40 @@ class TestSubcloudManager(base.DCManagerTestCase):
self.assertEqual(payload['management_end_ip'],
updated_subcloud.management_end_ip)
@mock.patch.object(subcloud_manager.SubcloudManager,
'_delete_subcloud_routes')
@mock.patch.object(subcloud_manager.SubcloudManager,
'_update_services_endpoint')
@mock.patch.object(subcloud_manager.SubcloudManager,
'_create_subcloud_route')
@mock.patch.object(subcloud_manager, 'OpenStackDriver')
def test_network_reconf_same_subnet(
self, mock_keystone_client, mock_create_route,
mock_update_endpoints, mock_delete_route):
subcloud = self.create_subcloud_static(
self.ctx,
name='subcloud1',
deploy_status=consts.DEPLOY_STATE_DONE)
db_api.subcloud_update(
self.ctx, subcloud.id,
availability_status=dccommon_consts.AVAILABILITY_ONLINE)
payload = {'name': "subcloud1",
'description': "subcloud description",
'location': "subcloud location",
'management_subnet': "192.168.101.0/24",
'management_start_ip': "192.168.101.3",
'management_end_ip': "192.168.101.49",
'management_gateway_ip': "192.168.101.1"}
sm = subcloud_manager.SubcloudManager()
sm._configure_system_controller_network(self.ctx, payload, subcloud)
mock_keystone_client.assert_called_once()
mock_create_route.assert_called_once()
mock_update_endpoints.assert_called_once()
self.assertFalse(mock_delete_route.called)
def test_update_subcloud_with_install_values(self):
subcloud = self.create_subcloud_static(
self.ctx,

View File

@@ -0,0 +1,53 @@
# Copyright (c) 2023 Wind River Systems, Inc.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
from dcmanager.common import utils
from dcmanager.tests import base
from dcmanager.tests.unit.common import fake_subcloud
from dcmanager.tests import utils as test_utils
class TestUtils(base.DCManagerTestCase):
def setUp(self):
super(TestUtils, self).setUp()
self.ctx = test_utils.dummy_context()
def test_has_network_reconfig_same_values(self):
subcloud = fake_subcloud.create_fake_subcloud(self.ctx)
payload = {"management_subnet": "192.168.101.0/24",
"management_gateway_address": "192.168.101.1",
"management_start_address": "192.168.101.2",
"management_end_address": "192.168.101.50"}
result = utils.has_network_reconfig(payload, subcloud)
self.assertFalse(result)
def test_has_network_reconfig_different_subnet(self):
subcloud = fake_subcloud.create_fake_subcloud(self.ctx)
payload = {"management_subnet": "192.168.102.0/24",
"management_gateway_address": "192.168.102.1",
"management_start_address": "192.168.102.2",
"management_end_address": "192.168.102.50"}
result = utils.has_network_reconfig(payload, subcloud)
self.assertTrue(result)
def test_has_network_reconfig_different_start_address(self):
subcloud = fake_subcloud.create_fake_subcloud(self.ctx)
payload = {"management_subnet": "192.168.101.0/24",
"management_gateway_address": "192.168.101.5",
"management_start_address": "192.168.101.7",
"management_end_address": "192.168.101.50"}
result = utils.has_network_reconfig(payload, subcloud)
self.assertTrue(result)