diff --git a/api-ref/source/api-ref-dcmanager-v1.rst b/api-ref/source/api-ref-dcmanager-v1.rst index 72db36f88..1a79e0f20 100644 --- a/api-ref/source/api-ref-dcmanager-v1.rst +++ b/api-ref/source/api-ref-dcmanager-v1.rst @@ -1524,9 +1524,9 @@ Response Example :language: json -****************************************************************************************************************************** -Shows sw-update options (defaults or per subcloud). Use ``RegionOne`` as subcloud for default options which are pre-configured -****************************************************************************************************************************** +************************************************************************************************************************************* +Shows sw-update options (defaults or per subcloud). Use ``SystemController`` as subcloud for default options which are pre-configured +************************************************************************************************************************************* .. rest_method:: GET /v1.0/sw-update-options/​{subcloud}​ @@ -1570,9 +1570,9 @@ Response Example :language: json -****************************************************************************************************** -Updates sw-update options, defaults or per subcloud. Use ``RegionOne`` as subcloud for default options -****************************************************************************************************** +************************************************************************************************************* +Updates sw-update options, defaults or per subcloud. Use ``SystemController`` as subcloud for default options +************************************************************************************************************* .. rest_method:: POST /v1.0/sw-update-options/​{subcloud}​ diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 1a534eb94..704b02e7f 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -27,7 +27,7 @@ subcloud_group_uri: subcloud_options_uri: description: | The name of the subcloud to which the options apply. - Use `RegionOne` for querying the default. + Use `SystemController` for querying the default. in: path required: true type: string diff --git a/distributedcloud/dccommon/consts.py b/distributedcloud/dccommon/consts.py index e2127c12e..6fab802ed 100644 --- a/distributedcloud/dccommon/consts.py +++ b/distributedcloud/dccommon/consts.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2024 Wind River Systems, Inc. +# Copyright (c) 2020-2025 Wind River Systems, Inc. # 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 @@ -28,12 +28,6 @@ ENDPOINT_TYPE_IDENTITY_OS = "identity_openstack" # openstack endpoint types ENDPOINT_TYPES_LIST_OS = [ENDPOINT_TYPE_IDENTITY_OS] -# distributed Cloud constants -# TODO(gherzmann) Remove the following constants in favor of the -# SYSTEM_CONTROLLER_NAME and DEFAULT_REGION_NAME constants -CLOUD_0 = "RegionOne" -VIRTUAL_MASTER_CLOUD = "SystemController" - SW_UPDATE_DEFAULT_TITLE = "all clouds default" ANSIBLE_OVERRIDES_PATH = "/opt/dc-vault/ansible" SOFTWARE_VAULT_DIR = "/opt/dc-vault/software" @@ -196,12 +190,6 @@ MIN_VERSION_FOR_DCAGENT = "24.09" # Well known region names SYSTEM_CONTROLLER_NAME = "SystemController" -DEFAULT_REGION_NAME = "RegionOne" - -SYSTEM_CONTROLLER_REGION_NAMES = { - DEFAULT_REGION_NAME, - SYSTEM_CONTROLLER_NAME, -} # Subcloud management state MANAGEMENT_UNMANAGED = "unmanaged" diff --git a/distributedcloud/dccommon/drivers/openstack/keystone_v3.py b/distributedcloud/dccommon/drivers/openstack/keystone_v3.py index 290f8f337..43b51167a 100644 --- a/distributedcloud/dccommon/drivers/openstack/keystone_v3.py +++ b/distributedcloud/dccommon/drivers/openstack/keystone_v3.py @@ -1,5 +1,5 @@ # Copyright 2012-2013 OpenStack Foundation -# Copyright (c) 2017-2021, 2024 Wind River Systems, Inc. +# Copyright (c) 2017-2021, 2024-2025 Wind River Systems, Inc. # 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 @@ -17,10 +17,10 @@ from keystoneauth1 import exceptions as keystone_exceptions from keystoneclient.v3.contrib import endpoint_filter from oslo_utils import importutils -from dccommon import consts from dccommon.drivers import base from dccommon.endpoint_cache import EndpointCache from dccommon import exceptions +from dccommon import utils # Ensure keystonemiddleware options are imported importutils.import_module("keystonemiddleware.auth_token") @@ -41,7 +41,8 @@ class KeystoneClient(base.DriverBase): self.endpoint_cache = EndpointCache(region_name, auth_url, fetch_subcloud_ips) self.session = self.endpoint_cache.admin_session self.keystone_client = self.endpoint_cache.keystone_client - if region_name in [consts.CLOUD_0, consts.VIRTUAL_MASTER_CLOUD]: + self.region_name = region_name + if region_name in utils.get_system_controller_region_names(): self.services_list = EndpointCache.master_services_list else: self.services_list = self.keystone_client.services.list() diff --git a/distributedcloud/dccommon/drivers/openstack/peer_site.py b/distributedcloud/dccommon/drivers/openstack/peer_site.py index a0690ef4c..1755832bc 100644 --- a/distributedcloud/dccommon/drivers/openstack/peer_site.py +++ b/distributedcloud/dccommon/drivers/openstack/peer_site.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023-2024 Wind River Systems, Inc. +# Copyright (c) 2023-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -17,7 +17,7 @@ from oslo_log import log from dccommon import consts from dccommon.drivers import base from dccommon import exceptions -from dccommon.utils import is_token_expiring_soon +from dccommon import utils LOG = log.getLogger(__name__) @@ -38,9 +38,12 @@ class PeerSiteDriver(object): auth_url, username, password, - region_name=consts.CLOUD_0, + region_name=None, endpoint_type=consts.KS_ENDPOINT_PUBLIC, ): + if not region_name: + region_name = utils.get_region_one_name() + if not (site_uuid and auth_url and username and password): raise exceptions.InvalidInputError @@ -134,7 +137,7 @@ class PeerSiteDriver(object): PeerSiteDriver._identity_tokens[site_uuid] = None return False - token_expiring_soon = is_token_expiring_soon( + token_expiring_soon = utils.is_token_expiring_soon( token=self._identity_tokens[site_uuid] ) @@ -164,12 +167,15 @@ class PeerKeystoneClient(base.DriverBase): auth_url, username, password, - region_name=consts.CLOUD_0, + region_name=None, project_name=consts.KS_ENDPOINT_PROJECT_DEFAULT, project_domain_name=consts.KS_ENDPOINT_PROJECT_DOMAIN_DEFAULT, user_domain_name=consts.KS_ENDPOINT_USER_DOMAIN_DEFAULT, auth_type=consts.KS_ENDPOINT_PUBLIC, ): + if not region_name: + region_name = utils.get_region_one_name() + if not (auth_url and username and password): raise exceptions.InvalidInputError self.auth_url = auth_url diff --git a/distributedcloud/dccommon/drivers/openstack/sdk_platform.py b/distributedcloud/dccommon/drivers/openstack/sdk_platform.py index 042749f4c..63d6e2a2f 100644 --- a/distributedcloud/dccommon/drivers/openstack/sdk_platform.py +++ b/distributedcloud/dccommon/drivers/openstack/sdk_platform.py @@ -1,4 +1,4 @@ -# Copyright 2017-2024 Wind River Inc +# Copyright 2017-2025 Wind River Inc # 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 @@ -33,7 +33,7 @@ from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon.endpoint_cache import EndpointCache from dccommon import exceptions -from dccommon.utils import is_token_expiring_soon +from dccommon import utils from dcdbsync.dbsyncclient.client import Client as dbsyncclient @@ -66,7 +66,7 @@ region_client_class_map = { class OpenStackDriver(object): """An OpenStack driver for managing external services clients. - :param region_name: The name of the region. Defaults to "RegionOne". + :param region_name: The name of the region. Defaults to the local region :type region_name: str :param thread_name: The name of the thread. Defaults to "dc". :type thread_name: str @@ -94,7 +94,7 @@ class OpenStackDriver(object): def __init__( self, - region_name: str = consts.DEFAULT_REGION_NAME, + region_name: str = None, thread_name: str = "dc", auth_url: str = None, region_clients: List[str] = SUPPORTED_REGION_CLIENTS, @@ -103,6 +103,9 @@ class OpenStackDriver(object): subcloud_management_ip: str = None, attempts: int = 3, ): + if not region_name: + region_name = utils.get_region_one_name() + self.region_name = region_name self.keystone_client = None @@ -113,7 +116,7 @@ class OpenStackDriver(object): self.dbsync_client = None # Update the endpoint cache for the subcloud with the specified IP - if subcloud_management_ip and region_name != consts.DEFAULT_REGION_NAME: + if subcloud_management_ip and region_name != utils.get_region_one_name(): # Check if the IP is different from the one already cached endpoint_map = EndpointCache.master_service_endpoint_map.get(region_name) if endpoint_map: @@ -134,7 +137,7 @@ class OpenStackDriver(object): region_name, KEYSTONE_CLIENT_NAME, self.keystone_client ) # Clear client object cache - if region_name != consts.DEFAULT_REGION_NAME: + if region_name != utils.get_region_one_name(): OpenStackDriver.os_clients_dict[region_name] = collections.defaultdict( dict ) @@ -290,7 +293,7 @@ class OpenStackDriver(object): if keystone_client and self._is_token_valid(region_name): self.keystone_client = keystone_client # Else if master region, create a new keystone client - elif region_name in (consts.DEFAULT_REGION_NAME, consts.SYSTEM_CONTROLLER_NAME): + elif region_name in utils.get_system_controller_region_names(): self.initialize_keystone_client(auth_url, fetch_subcloud_ips, attempts) os_clients_dict[region_name][KEYSTONE_CLIENT_NAME] = self.keystone_client @@ -422,7 +425,7 @@ class OpenStackDriver(object): return False # If token is expiring soon, reset cached data and return False. - if is_token_expiring_soon(token=cached_tokens[region_name]): + if utils.is_token_expiring_soon(token=cached_tokens[region_name]): LOG.info( f"The cached keystone token for subcloud {region_name} will " f"expire soon {cached_tokens[region_name]['expires_at']}" diff --git a/distributedcloud/dccommon/endpoint_cache.py b/distributedcloud/dccommon/endpoint_cache.py index 8a7f8ecba..fa4155550 100644 --- a/distributedcloud/dccommon/endpoint_cache.py +++ b/distributedcloud/dccommon/endpoint_cache.py @@ -1,5 +1,5 @@ # Copyright 2015 Huawei Technologies Co., Ltd. -# Copyright (c) 2018-2024 Wind River Systems, Inc. +# Copyright (c) 2018-2025 Wind River Systems, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -137,7 +137,7 @@ class CachedV3Password(v3.Password): # Check if we should attempt to build a custom endpoint if ( - region_name not in consts.SYSTEM_CONTROLLER_REGION_NAMES + not utils.is_system_controller_region(region_name) and interface == consts.KS_ENDPOINT_ADMIN and self.auth_url != CONF.endpoint_cache.auth_uri ): @@ -307,7 +307,7 @@ class EndpointCache(object): if ( not auth_url and region_name - and region_name not in [consts.CLOUD_0, consts.VIRTUAL_MASTER_CLOUD] + and region_name not in utils.get_system_controller_region_names() ): try: sc_auth_url = self.service_endpoint_map["keystone"] @@ -413,8 +413,7 @@ class EndpointCache(object): :return: True if the region is a central cloud, False otherwise. :rtype: bool """ - central_cloud_regions = [consts.CLOUD_0, consts.VIRTUAL_MASTER_CLOUD] - return region_name in central_cloud_regions + return region_name in utils.get_system_controller_region_names() @staticmethod def _get_master_endpoint_map() -> dict: @@ -631,7 +630,7 @@ class EndpointCache(object): def _create_master_cached_data(self) -> None: EndpointCache.master_keystone_client = ks_client.Client( - session=self.admin_session, region_name=consts.CLOUD_0 + session=self.admin_session, region_name=utils.get_region_one_name() ) try: EndpointCache.master_token = ( diff --git a/distributedcloud/dccommon/subcloud_install.py b/distributedcloud/dccommon/subcloud_install.py index d00060a3d..6375c97ba 100644 --- a/distributedcloud/dccommon/subcloud_install.py +++ b/distributedcloud/dccommon/subcloud_install.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2024 Wind River Systems, Inc. +# Copyright (c) 2021-2025 Wind River Systems, Inc. # 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 @@ -117,14 +117,15 @@ class SubcloudInstall(object): @staticmethod def get_sysinv_client(): + region_name = dccommon_utils.get_region_one_name() ks_client = OpenStackDriver( - region_name=consts.DEFAULT_REGION_NAME, + region_name=region_name, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client session = ks_client.session endpoint = ks_client.endpoint_cache.get_endpoint("sysinv") - return SysinvClient(consts.CLOUD_0, session, endpoint=endpoint) + return SysinvClient(region_name, session, endpoint=endpoint) @staticmethod def format_address(ip_address): diff --git a/distributedcloud/dccommon/tests/unit/drivers/test_sysinv_v1.py b/distributedcloud/dccommon/tests/unit/drivers/test_sysinv_v1.py index 0665b4df5..b1dcb27c7 100644 --- a/distributedcloud/dccommon/tests/unit/drivers/test_sysinv_v1.py +++ b/distributedcloud/dccommon/tests/unit/drivers/test_sysinv_v1.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # 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 @@ -13,14 +13,17 @@ # import mock +from oslo_utils import uuidutils -from dccommon import consts as dccommon_consts from dccommon.drivers.openstack import sysinv_v1 from dccommon import exceptions from dccommon.tests import base from dccommon.tests import utils +REGION_NAME = uuidutils.generate_uuid().replace("-", "") + + class FakeInterface(object): def __init__(self, ifname, uuid): self.ifname = ifname @@ -69,9 +72,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_get_controller_hosts(self, mock_sysinvclient_init): controller_list = ["controller-0", "controller-1"] mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.ihost.list_personality = mock.MagicMock() sysinv_client.sysinv_client.ihost.list_personality.return_value = ( @@ -84,9 +85,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_get_address_pools(self, mock_sysinvclient_init): pool_list = [FakeAddressPool("pool-uuid")] mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type.return_value = ( @@ -98,9 +97,7 @@ class TestSysinvClient(base.DCCommonTestCase): @mock.patch.object(sysinv_v1.SysinvClient, "__init__") def test_get_address_pools_exception(self, mock_sysinvclient_init): mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type.side_effect = ( @@ -115,9 +112,7 @@ class TestSysinvClient(base.DCCommonTestCase): interface = FakeInterface("interface", "uuid") interface_network = FakeInterfaceNetwork("mgmt", "interface") mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.iinterface.list = mock.MagicMock() sysinv_client.sysinv_client.iinterface.list.return_value = [interface] @@ -131,9 +126,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_get_management_address_pools(self, mock_sysinvclient_init): pool = FakeAddressPool("pool-uuid") mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type.return_value = [ @@ -149,9 +142,7 @@ class TestSysinvClient(base.DCCommonTestCase): pool_2 = FakeAddressPool("pool-uuid-2") pool_list = [pool_1, pool_2] mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type.return_value = ( @@ -167,9 +158,7 @@ class TestSysinvClient(base.DCCommonTestCase): pool_2 = FakeAddressPool("pool-uuid-2") pool_list = [pool_1, pool_2] mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type.return_value = ( @@ -184,9 +173,7 @@ class TestSysinvClient(base.DCCommonTestCase): interface = FakeInterface("interface", "uuid") interface_network = FakeInterfaceNetwork("admin", "interface") mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.iinterface.list = mock.MagicMock() sysinv_client.sysinv_client.iinterface.list.return_value = [interface] @@ -200,9 +187,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_get_admin_address_pools(self, mock_sysinvclient_init): pool = FakeAddressPool("pool-uuid") mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type = mock.MagicMock() sysinv_client.sysinv_client.address_pool.list_by_network_type.return_value = [ @@ -216,9 +201,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_create_route(self, mock_sysinvclient_init): fake_route = utils.create_route_dict(base.ROUTE_0) mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.route.create = mock.MagicMock() sysinv_client.create_route( @@ -240,9 +223,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_delete_route(self, mock_sysinvclient_init): fake_route = utils.create_route_dict(base.ROUTE_0) mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.route.delete = mock.MagicMock() sysinv_client.sysinv_client.route.list_by_interface = mock.MagicMock() @@ -267,9 +248,7 @@ class TestSysinvClient(base.DCCommonTestCase): def test_delete_route_not_exist(self, mock_sysinvclient_init): fake_route = utils.create_route_dict(base.ROUTE_0) mock_sysinvclient_init.return_value = None - sysinv_client = sysinv_v1.SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, None - ) + sysinv_client = sysinv_v1.SysinvClient(REGION_NAME, None) sysinv_client.sysinv_client = mock.MagicMock() sysinv_client.sysinv_client.route.delete = mock.MagicMock() sysinv_client.sysinv_client.route.list_by_interface = mock.MagicMock() diff --git a/distributedcloud/dccommon/utils.py b/distributedcloud/dccommon/utils.py index eb525e7ae..4fe553437 100644 --- a/distributedcloud/dccommon/utils.py +++ b/distributedcloud/dccommon/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2024 Wind River Systems, Inc. +# Copyright (c) 2020-2025 Wind River Systems, Inc. # 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 @@ -25,6 +25,7 @@ from typing import Callable from eventlet.green import subprocess import netaddr +from oslo_config import cfg from oslo_log import log as logging from oslo_utils import timeutils @@ -37,6 +38,8 @@ from dccommon.subprocess_cleanup import kill_subprocess_group from dccommon.subprocess_cleanup import SubprocessCleanup from dcorch.common.i18n import _ +CONF = cfg.CONF + LOG = logging.getLogger(__name__) ANSIBLE_PASSWD_PARMS = ["ansible_ssh_pass", "ansible_become_pass"] SCRIPT_PASSWD_PARMS = ["sysadmin_password", "password"] @@ -484,3 +487,21 @@ def build_subcloud_endpoint(ip: str, service: str) -> str: formatted_ip = f"[{ip}]" if netaddr.IPAddress(ip).version == 6 else ip endpoint = endpoint.format(formatted_ip) return endpoint + + +@functools.lru_cache(maxsize=1) +def get_region_one_name() -> str: + return CONF.keystone_authtoken.region_name + + +@functools.lru_cache(maxsize=1) +def get_system_controller_region_names() -> tuple[str]: + return (consts.SYSTEM_CONTROLLER_NAME, CONF.keystone_authtoken.region_name) + + +def is_region_one(region_name: str) -> bool: + return region_name == get_region_one_name() + + +def is_system_controller_region(region_name: str) -> bool: + return region_name in get_system_controller_region_names() diff --git a/distributedcloud/dcmanager/api/controllers/v1/peer_group_association.py b/distributedcloud/dcmanager/api/controllers/v1/peer_group_association.py index fa40816a1..238e1c35b 100644 --- a/distributedcloud/dcmanager/api/controllers/v1/peer_group_association.py +++ b/distributedcloud/dcmanager/api/controllers/v1/peer_group_association.py @@ -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 # @@ -14,8 +14,8 @@ import pecan from pecan import expose from pecan import request -from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.sysinv_v1 import SysinvClient +from dccommon import utils from dcmanager.api.controllers import restcomm from dcmanager.api.policies import ( peer_group_association as peer_group_association_policy, @@ -85,7 +85,7 @@ class PeerGroupAssociationsController(restcomm.GenericPathController): def _validate_peer_group_leader_id(self, system_leader_id): ks_client = psd_common.get_ks_client() sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + utils.get_region_one_name(), ks_client.session, endpoint=ks_client.endpoint_cache.get_endpoint("sysinv"), ) diff --git a/distributedcloud/dcmanager/api/controllers/v1/subcloud_peer_group.py b/distributedcloud/dcmanager/api/controllers/v1/subcloud_peer_group.py index ea303ac7c..720ee354a 100644 --- a/distributedcloud/dcmanager/api/controllers/v1/subcloud_peer_group.py +++ b/distributedcloud/dcmanager/api/controllers/v1/subcloud_peer_group.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023-2024 Wind River Systems, Inc. +# Copyright (c) 2023-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -17,7 +17,6 @@ import pecan from pecan import expose from pecan import request -from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dcmanager.api.controllers import restcomm @@ -74,12 +73,11 @@ class SubcloudPeerGroupsController(restcomm.GenericPathController): def _get_local_system(self): try: ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ) sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + ks_client.region_name, ks_client.keystone_client.session, endpoint=ks_client.keystone_client.endpoint_cache.get_endpoint( "sysinv" diff --git a/distributedcloud/dcmanager/api/controllers/v1/subclouds.py b/distributedcloud/dcmanager/api/controllers/v1/subclouds.py index bd5809122..653e142a2 100644 --- a/distributedcloud/dcmanager/api/controllers/v1/subclouds.py +++ b/distributedcloud/dcmanager/api/controllers/v1/subclouds.py @@ -1,5 +1,5 @@ # Copyright (c) 2017 Ericsson AB. -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -534,9 +534,7 @@ class SubcloudsController(object): @staticmethod def is_valid_software_deploy_state(): try: - m_os_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None - ).keystone_client + m_os_ks_client = OpenStackDriver(region_clients=None).keystone_client software_endpoint = m_os_ks_client.endpoint_cache.get_endpoint( dccommon_consts.ENDPOINT_NAME_USM ) diff --git a/distributedcloud/dcmanager/api/controllers/v1/sw_update_options.py b/distributedcloud/dcmanager/api/controllers/v1/sw_update_options.py index 41bec59c2..dd3346fa8 100644 --- a/distributedcloud/dcmanager/api/controllers/v1/sw_update_options.py +++ b/distributedcloud/dcmanager/api/controllers/v1/sw_update_options.py @@ -1,5 +1,5 @@ # Copyright (c) 2017 Ericsson AB. -# Copyright (c) 2017-2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2017-2022, 2024-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -35,6 +35,10 @@ from dcmanager.rpc import client as rpc_client CONF = cfg.CONF LOG = logging.getLogger(__name__) +# TODO(gherzmann): remove the "RegionOne", it's being kept for +# now to maintain backwards compatibility with older clients +REGION_ONE = "RegionOne" + class SwUpdateOptionsController(object): @@ -83,7 +87,7 @@ class SwUpdateOptionsController(object): return result - elif subcloud_ref == dccommon_consts.DEFAULT_REGION_NAME: + elif subcloud_ref in (dccommon_consts.SYSTEM_CONTROLLER_NAME, REGION_ONE): # Default options requested, guaranteed to succeed return utils.get_sw_update_opts(context) @@ -130,7 +134,7 @@ class SwUpdateOptionsController(object): if not payload: pecan.abort(400, _("Body required")) - if subcloud_ref == dccommon_consts.DEFAULT_REGION_NAME: + if subcloud_ref in (dccommon_consts.SYSTEM_CONTROLLER_NAME, REGION_ONE): # update default options subcloud_name = dccommon_consts.SW_UPDATE_DEFAULT_TITLE @@ -224,7 +228,7 @@ class SwUpdateOptionsController(object): ) context = restcomm.extract_context_from_environ() - if subcloud_ref == dccommon_consts.DEFAULT_REGION_NAME: + if subcloud_ref in (dccommon_consts.SYSTEM_CONTROLLER_NAME, REGION_ONE): # Delete defaults. # Note by deleting these, the next get will repopulate with # the global constants. diff --git a/distributedcloud/dcmanager/audit/firmware_audit.py b/distributedcloud/dcmanager/audit/firmware_audit.py index a51f26e00..ea82fd768 100644 --- a/distributedcloud/dcmanager/audit/firmware_audit.py +++ b/distributedcloud/dcmanager/audit/firmware_audit.py @@ -1,5 +1,5 @@ # Copyright 2017 Ericsson AB. -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ from oslo_log import log as logging from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.sysinv_v1 import SysinvClient -from dccommon.utils import log_subcloud_msg +from dccommon import utils as cutils from dcmanager.common import consts from dcmanager.common import utils @@ -91,13 +91,12 @@ class FirmwareAudit(object): """ try: m_os_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client endpoint = m_os_ks_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + m_os_ks_client.region_name, m_os_ks_client.session, endpoint=endpoint, ) @@ -230,7 +229,7 @@ class FirmwareAudit(object): subcloud_image = subcloud_device_images[uuid] except Exception: msg = "Cannot retrieve device image, skip firmware audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return False if cls._check_image_match(subcloud_image, image): @@ -267,7 +266,7 @@ class FirmwareAudit(object): enabled_host_device_list.append(device) except Exception: msg = "Cannot retrieve host device list, skip firmware audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit # If there are no enabled devices on the subcloud, exit the firmware audit @@ -278,20 +277,20 @@ class FirmwareAudit(object): try: subcloud_device_image_states = sysinv_client.get_device_image_states() msg = f"Device_image_states: {subcloud_device_image_states}" - log_subcloud_msg(LOG.debug, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.debug, msg, subcloud_name) except Exception: msg = "Cannot retrieve device image states, skip firmware audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit # Retrieve device label list for all devices on this subcloud. try: subcloud_device_label_list = sysinv_client.get_device_label_list() msg = f"Subcloud_device_label_list: {subcloud_device_label_list}" - log_subcloud_msg(LOG.debug, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.debug, msg, subcloud_name) except Exception: msg = "Cannot retrieve device label list, skip firmware audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit # Retrieve the device images on this subcloud. @@ -302,10 +301,10 @@ class FirmwareAudit(object): image.uuid: image for image in subcloud_device_images } msg = f"Device_images: {subcloud_device_images}" - log_subcloud_msg(LOG.debug, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.debug, msg, subcloud_name) except Exception: msg = "Cannot retrieve device images, skip firmware audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit return ( @@ -337,7 +336,7 @@ class FirmwareAudit(object): # sync status as in-sync if not enabled_host_device_list: msg = "No enabled devices on the subcloud, exiting firmware audit" - log_subcloud_msg(LOG.info, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.info, msg, subcloud_name) return dccommon_consts.SYNC_STATUS_IN_SYNC elif enabled_host_device_list == dccommon_consts.SKIP_AUDIT: return None diff --git a/distributedcloud/dcmanager/audit/kube_rootca_update_audit.py b/distributedcloud/dcmanager/audit/kube_rootca_update_audit.py index d9d1557d5..0cb1ef29c 100644 --- a/distributedcloud/dcmanager/audit/kube_rootca_update_audit.py +++ b/distributedcloud/dcmanager/audit/kube_rootca_update_audit.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2021-2024 Wind River Systems, Inc. +# Copyright (c) 2021-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -13,7 +13,7 @@ from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.fm import FmClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.sysinv_v1 import SysinvClient -from dccommon.utils import log_subcloud_msg +from dccommon import utils as cutils from dcmanager.common import utils from dcmanager.db.sqlalchemy import models @@ -50,13 +50,12 @@ class KubeRootcaUpdateAudit(object): """ try: m_os_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client endpoint = m_os_ks_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + m_os_ks_client.region_name, m_os_ks_client.session, endpoint=endpoint, ) @@ -98,7 +97,7 @@ class KubeRootcaUpdateAudit(object): msg = ( f"Failed to get Kubernetes root CA status, skip {AUDIT_TYPE} audit." ) - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit if success: @@ -108,7 +107,7 @@ class KubeRootcaUpdateAudit(object): detected_alarms = fm_client.get_alarms_by_ids(KUBE_ROOTCA_ALARM_LIST) except Exception: msg = f"Failed to get alarms by id, skip {AUDIT_TYPE} audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit return ALARM_BASED, detected_alarms @@ -168,7 +167,7 @@ class KubeRootcaUpdateAudit(object): # Skip the audit if cannot get the region one cert ID. if not regionone_rootca_certid: msg = f"No region one audit data, exiting {AUDIT_TYPE} audit" - log_subcloud_msg(LOG.debug, msg, subcloud.name) + cutils.log_subcloud_msg(LOG.debug, msg, subcloud.name) return dccommon_consts.SYNC_STATUS_IN_SYNC sync_status = self.get_subcloud_sync_status( @@ -220,7 +219,7 @@ class KubeRootcaUpdateAudit(object): "Failed to get Kubernetes root CA cert id, error: " f"{subcloud_cert_data.error}, skip {AUDIT_TYPE} audit." ) - log_subcloud_msg(LOG.error, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.error, msg, subcloud_name) return None out_of_sync = subcloud_cert_data.cert_id != regionone_rootca_certid diff --git a/distributedcloud/dcmanager/audit/kubernetes_audit.py b/distributedcloud/dcmanager/audit/kubernetes_audit.py index a12fd0d8c..721e9fe9c 100644 --- a/distributedcloud/dcmanager/audit/kubernetes_audit.py +++ b/distributedcloud/dcmanager/audit/kubernetes_audit.py @@ -1,5 +1,5 @@ # Copyright 2017 Ericsson AB. -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ from oslo_log import log as logging from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.sysinv_v1 import SysinvClient -from dccommon.utils import log_subcloud_msg +from dccommon import utils as cutils from dcmanager.common import utils @@ -62,13 +62,12 @@ class KubernetesAudit(object): """ try: m_os_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client endpoint = m_os_ks_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + m_os_ks_client.region_name, m_os_ks_client.session, endpoint=endpoint, ) @@ -100,7 +99,7 @@ class KubernetesAudit(object): subcloud_kube_upgrades = sysinv_client.get_kube_upgrades() except Exception: msg = "Failed to get kubernetes upgrades, skip kubernetes audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit # If there is a kubernetes upgrade operation in the subcloud, @@ -112,7 +111,7 @@ class KubernetesAudit(object): subcloud_kubernetes_versions = sysinv_client.get_kube_versions() except Exception: msg = "Failed to get kubernetes versions, skip kubernetes audit." - log_subcloud_msg(LOG.exception, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.exception, msg, subcloud_name) return skip_audit return None, subcloud_kubernetes_versions @@ -140,7 +139,7 @@ class KubernetesAudit(object): # If there is a kubernetes upgrade operation in the subcloud, # the subcloud can immediately be flagged as out of sync msg = "Kubernetes upgrade exists" - log_subcloud_msg(LOG.debug, msg, subcloud_name) + cutils.log_subcloud_msg(LOG.debug, msg, subcloud_name) return dccommon_consts.SYNC_STATUS_OUT_OF_SYNC # We will consider it out of sync even for 'partial' state diff --git a/distributedcloud/dcmanager/audit/software_audit.py b/distributedcloud/dcmanager/audit/software_audit.py index 3ac5ca448..0bb9060c0 100644 --- a/distributedcloud/dcmanager/audit/software_audit.py +++ b/distributedcloud/dcmanager/audit/software_audit.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2024 Wind River Systems, Inc. +# Copyright (c) 2024-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -51,7 +51,6 @@ class SoftwareAudit(object): """ try: m_os_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client @@ -60,7 +59,7 @@ class SoftwareAudit(object): ) software_client = SoftwareClient( m_os_ks_client.session, - dccommon_consts.DEFAULT_REGION_NAME, + m_os_ks_client.region_name, endpoint=software_endpoint, ) except Exception: diff --git a/distributedcloud/dcmanager/common/phased_subcloud_deploy.py b/distributedcloud/dcmanager/common/phased_subcloud_deploy.py index 862683225..dc8e225ea 100644 --- a/distributedcloud/dcmanager/common/phased_subcloud_deploy.py +++ b/distributedcloud/dcmanager/common/phased_subcloud_deploy.py @@ -20,6 +20,7 @@ from dccommon.drivers.openstack import patching_v1 from dccommon.drivers.openstack.patching_v1 import PatchingClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.sysinv_v1 import SysinvClient +from dccommon import utils as cutils from dcmanager.common import consts from dcmanager.common.context import RequestContext from dcmanager.common import exceptions @@ -59,10 +60,11 @@ BOOTSTRAP_VALUES_ADDRESSES = [ ] -def get_ks_client( - region_name=dccommon_consts.DEFAULT_REGION_NAME, management_ip: str = None -): +def get_ks_client(region_name: str = None, management_ip: str = None): """This will get a new keystone client (and new token)""" + if not region_name: + region_name = cutils.get_region_one_name() + try: os_client = OpenStackDriver( region_name=region_name, @@ -72,7 +74,7 @@ def get_ks_client( ) return os_client.keystone_client except Exception: - LOG.warn("Failure initializing KeystoneClient for region %s" % region_name) + LOG.warn(f"Failure initializing KeystoneClient for region {region_name}") raise @@ -149,7 +151,7 @@ def validate_bootstrap_values(payload: dict): def validate_system_controller_patch_status(operation: str): ks_client = get_ks_client() patching_client = PatchingClient( - dccommon_consts.DEFAULT_REGION_NAME, + cutils.get_region_one_name(), ks_client.session, endpoint=ks_client.endpoint_cache.get_endpoint("patching"), ) @@ -319,15 +321,12 @@ def validate_subcloud_config( # If a subcloud group is not passed, use the default group_id = payload.get("group_id", consts.DEFAULT_SUBCLOUD_GROUP_ID) - if payload.get("name") in [ - dccommon_consts.DEFAULT_REGION_NAME, - dccommon_consts.SYSTEM_CONTROLLER_NAME, - ]: + if cutils.is_system_controller_region(payload.get("name")): pecan.abort( 400, _("name cannot be %(bad_name1)s or %(bad_name2)s") % { - "bad_name1": dccommon_consts.DEFAULT_REGION_NAME, + "bad_name1": cutils.get_region_one_name, "bad_name2": dccommon_consts.SYSTEM_CONTROLLER_NAME, }, ) @@ -607,15 +606,16 @@ def validate_group_id(context, group_id): pecan.abort(400, _("Invalid group_id")) -def get_sysinv_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): +def get_sysinv_client(region_name: str = None) -> SysinvClient: + if not region_name: + region_name = cutils.get_region_one_name() + ks_client = get_ks_client(region_name) endpoint = ks_client.endpoint_cache.get_endpoint("sysinv") return SysinvClient(region_name, ks_client.session, endpoint=endpoint) -def get_network_address_pools( - network="management", region_name=dccommon_consts.DEFAULT_REGION_NAME -): +def get_network_address_pools(network="management", region_name: str = None): """Get the region network address pools""" sysinv_client = get_sysinv_client(region_name) if network == "admin": diff --git a/distributedcloud/dcmanager/common/utils.py b/distributedcloud/dcmanager/common/utils.py index f7f3479e1..1f9e91b90 100644 --- a/distributedcloud/dcmanager/common/utils.py +++ b/distributedcloud/dcmanager/common/utils.py @@ -50,6 +50,7 @@ from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon.drivers.openstack import vim from dccommon import exceptions as dccommon_exceptions from dccommon import kubeoperator +from dccommon import utils as cutils from dcmanager.audit import alarm_aggregation from dcmanager.common import consts from dcmanager.common import context @@ -812,13 +813,8 @@ def get_region_from_subcloud_address(payload): err_cause = "exception %s occurred" % type(e).__name__ subcloud_region = None - system_regions = [ - dccommon_consts.DEFAULT_REGION_NAME, - dccommon_consts.SYSTEM_CONTROLLER_NAME, - ] - - if subcloud_region in system_regions: - err_cause = "region %s is not valid for a subcloud" % subcloud_region + if subcloud_region in cutils.get_system_controller_region_names(): + err_cause = f"region {subcloud_region} is not valid for a subcloud" subcloud_region = None if err_cause: @@ -1169,9 +1165,7 @@ def is_subcloud_healthy(subcloud_region, management_ip: str = None): return False -def get_system_controller_software_list( - region_name=dccommon_consts.DEFAULT_REGION_NAME, -): +def get_system_controller_software_list(region_name: str = None) -> list[dict]: """Get software list from USM API This function is responsible for querying the USM API for the list of releases @@ -1188,6 +1182,9 @@ def get_system_controller_software_list( list of dict: each dict item contains the parameters that identify the release from API response """ + if not region_name: + region_name = cutils.get_region_one_name() + try: os_client = OpenStackDriver( region_name=region_name, @@ -2084,13 +2081,12 @@ def validate_name( def get_local_system(): m_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=fetch_subcloud_mgmt_ips, ).keystone_client endpoint = m_ks_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, m_ks_client.session, endpoint=endpoint + m_ks_client.region_name, m_ks_client.session, endpoint=endpoint ) system = sysinv_client.get_system() return system diff --git a/distributedcloud/dcmanager/manager/subcloud_manager.py b/distributedcloud/dcmanager/manager/subcloud_manager.py index 35481ad68..c68cc7456 100644 --- a/distributedcloud/dcmanager/manager/subcloud_manager.py +++ b/distributedcloud/dcmanager/manager/subcloud_manager.py @@ -1,5 +1,5 @@ # Copyright 2017 Ericsson AB. -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -45,6 +45,7 @@ from tsconfig.tsconfig import SW_VERSION import yaml from dccommon import consts as dccommon_consts +from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon import endpoint_cache @@ -1562,13 +1563,12 @@ class SubcloudManager(manager.Manager): try: # Write ansible based on rehome_data m_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client endpoint = m_ks_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + m_ks_client.region_name, m_ks_client.session, endpoint=endpoint, ) @@ -1678,7 +1678,6 @@ class SubcloudManager(manager.Manager): # Create a new route to this subcloud on the management interface # on both controllers. m_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client @@ -1689,7 +1688,7 @@ class SubcloudManager(manager.Manager): ) endpoint = m_ks_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + m_ks_client.region_name, m_ks_client.session, endpoint=endpoint, ) @@ -3179,7 +3178,9 @@ class SubcloudManager(manager.Manager): ] self._write_deploy_files(payload, subcloud_name) - def _delete_subcloud_routes(self, keystone_client, subcloud): + def _delete_subcloud_routes( + self, keystone_client: KeystoneClient, subcloud: Subcloud + ): """Delete the routes to this subcloud""" # Delete the route to this subcloud on the management interface on @@ -3187,7 +3188,7 @@ class SubcloudManager(manager.Manager): management_subnet = netaddr.IPNetwork(subcloud.management_subnet) endpoint = keystone_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + keystone_client.region_name, keystone_client.session, endpoint=endpoint, ) @@ -3240,7 +3241,6 @@ class SubcloudManager(manager.Manager): # down so is not accessible. Therefore set up a session with the # Central Region Keystone ONLY. keystone_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client @@ -3698,7 +3698,6 @@ class SubcloudManager(manager.Manager): f"{systemcontroller_gateway_ip.split(',')[0]}. Replacing routes..." ) m_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client @@ -3926,7 +3925,6 @@ class SubcloudManager(manager.Manager): try: m_ks_client = OpenStackDriver( - region_name=dccommon_consts.DEFAULT_REGION_NAME, region_clients=None, fetch_subcloud_ips=utils.fetch_subcloud_mgmt_ips, ).keystone_client @@ -3961,14 +3959,17 @@ class SubcloudManager(manager.Manager): self._delete_subcloud_routes(m_ks_client, subcloud) def _create_subcloud_route( - self, payload, keystone_client, systemcontroller_gateway_ip + self, + payload: dict, + keystone_client: KeystoneClient, + systemcontroller_gateway_ip: str, ): subcloud_subnet = netaddr.IPNetwork( utils.get_primary_management_subnet(payload) ) endpoint = keystone_client.endpoint_cache.get_endpoint("sysinv") sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + keystone_client.region_name, keystone_client.session, endpoint=endpoint, ) @@ -4154,7 +4155,9 @@ class SubcloudManager(manager.Manager): @utils.synchronized("regionone-data-cache", external=False) def _get_cached_regionone_data( - self, regionone_keystone_client, regionone_sysinv_client=None + self, + regionone_keystone_client: KeystoneClient, + regionone_sysinv_client: SysinvClient = None, ): if ( not SubcloudManager.regionone_data @@ -4181,7 +4184,7 @@ class SubcloudManager(manager.Manager): "sysinv" ) regionone_sysinv_client = SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + regionone_keystone_client.region_name, regionone_keystone_client.session, endpoint=endpoint, ) diff --git a/distributedcloud/dcmanager/manager/system_peer_manager.py b/distributedcloud/dcmanager/manager/system_peer_manager.py index eb212f6e5..b3b3fbe3f 100644 --- a/distributedcloud/dcmanager/manager/system_peer_manager.py +++ b/distributedcloud/dcmanager/manager/system_peer_manager.py @@ -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 # @@ -210,11 +210,11 @@ class SystemPeerManager(manager.Manager): p_ks_client = SystemPeerManager.get_peer_ks_client(peer) sysinv_endpoint = p_ks_client.session.get_endpoint( service_type="platform", - region_name=dccommon_consts.DEFAULT_REGION_NAME, + region_name=p_ks_client.region_name, interface=dccommon_consts.KS_ENDPOINT_PUBLIC, ) return SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + p_ks_client.region_name, p_ks_client.session, endpoint_type=dccommon_consts.KS_ENDPOINT_PUBLIC, endpoint=sysinv_endpoint, diff --git a/distributedcloud/dcmanager/orchestrator/cache/clients.py b/distributedcloud/dcmanager/orchestrator/cache/clients.py index 1f22ac231..88d63b00b 100644 --- a/distributedcloud/dcmanager/orchestrator/cache/clients.py +++ b/distributedcloud/dcmanager/orchestrator/cache/clients.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2024 Wind River Systems, Inc. +# Copyright (c) 2024-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -8,10 +8,11 @@ import socket from keystoneauth1 import exceptions as keystone_exceptions from oslo_log import log as logging -from dccommon import consts as dccommon_consts +from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.software_v1 import SoftwareClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient +from dccommon import utils as cutils from dcmanager.common import utils LOG = logging.getLogger(__name__) @@ -27,7 +28,7 @@ CLIENT_READ_MAX_ATTEMPTS = 2 def get_sysinv_client(): ks_client = get_keystone_client() return SysinvClient( - dccommon_consts.DEFAULT_REGION_NAME, + ks_client.region_name, ks_client.session, endpoint=ks_client.endpoint_cache.get_endpoint("sysinv"), timeout=CLIENT_READ_TIMEOUT_SECONDS, @@ -42,8 +43,10 @@ def get_software_client(): ) -def get_keystone_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): +def get_keystone_client(region_name: str = None) -> KeystoneClient: """Construct a (cached) keystone client (and token)""" + if not region_name: + region_name = cutils.get_region_one_name() try: os_client = OpenStackDriver( diff --git a/distributedcloud/dcmanager/orchestrator/orch_thread.py b/distributedcloud/dcmanager/orchestrator/orch_thread.py index 90c60da4a..007c8110e 100644 --- a/distributedcloud/dcmanager/orchestrator/orch_thread.py +++ b/distributedcloud/dcmanager/orchestrator/orch_thread.py @@ -1,5 +1,5 @@ # Copyright 2017 Ericsson AB. -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -24,11 +24,13 @@ from keystoneauth1 import exceptions as keystone_exceptions from oslo_log import log as logging from dccommon import consts as dccommon_consts +from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.patching_v1 import PatchingClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.software_v1 import SoftwareClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon.drivers.openstack import vim +from dccommon import utils as cutils from dcmanager.common import consts from dcmanager.common import context from dcmanager.common import exceptions @@ -134,7 +136,7 @@ class OrchThread(threading.Thread): self.thread_group_manager.stop() @staticmethod - def get_ks_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_ks_client(region_name: str = None) -> KeystoneClient: """This will get a cached keystone client (and token) throws an exception if keystone client cannot be initialized @@ -147,18 +149,18 @@ class OrchThread(threading.Thread): return os_client.keystone_client @staticmethod - def get_vim_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_vim_client(region_name: str = None) -> vim.VimClient: ks_client = OrchThread.get_ks_client(region_name) - return vim.VimClient(region_name, ks_client.session) + return vim.VimClient(ks_client.region_name, ks_client.session) @staticmethod - def get_sysinv_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_sysinv_client(region_name: str = None) -> SysinvClient: ks_client = OrchThread.get_ks_client(region_name) endpoint = ks_client.endpoint_cache.get_endpoint("sysinv") - return SysinvClient(region_name, ks_client.session, endpoint=endpoint) + return SysinvClient(ks_client.region_name, ks_client.session, endpoint=endpoint) @staticmethod - def get_software_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_software_client(region_name: str = None) -> SoftwareClient: ks_client = OrchThread.get_ks_client(region_name) return SoftwareClient( ks_client.session, @@ -166,16 +168,16 @@ class OrchThread(threading.Thread): ) @staticmethod - def get_patching_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_patching_client(region_name: str = None) -> PatchingClient: ks_client = OrchThread.get_ks_client(region_name) - return PatchingClient(region_name, ks_client.session) + return PatchingClient(ks_client.region_name, ks_client.session) @staticmethod def get_region_name(strategy_step): """Get the region name for a strategy step""" if strategy_step.subcloud_id is None: # This is the SystemController. - return dccommon_consts.DEFAULT_REGION_NAME + return cutils.get_region_one_name() return strategy_step.subcloud.region_name @staticmethod @@ -183,7 +185,7 @@ class OrchThread(threading.Thread): """Get the subcloud name for a strategy step""" if strategy_step.subcloud_id is None: # This is the SystemController. - return dccommon_consts.DEFAULT_REGION_NAME + return cutils.get_region_one_name() return strategy_step.subcloud.name @staticmethod diff --git a/distributedcloud/dcmanager/orchestrator/orchestrator_worker.py b/distributedcloud/dcmanager/orchestrator/orchestrator_worker.py index 6103e932e..40d9a1c0d 100644 --- a/distributedcloud/dcmanager/orchestrator/orchestrator_worker.py +++ b/distributedcloud/dcmanager/orchestrator/orchestrator_worker.py @@ -81,19 +81,11 @@ class OrchestratorWorker(object): @staticmethod def _get_subcloud_name(step): """Get the subcloud name for a step""" - - if step.subcloud_id is None: - # This is the SystemController. - return dccommon_consts.DEFAULT_REGION_NAME return step.subcloud.name @staticmethod def _get_region_name(step): """Get the region name for a step""" - - if step.subcloud_id is None: - # This is the SystemController. - return dccommon_consts.DEFAULT_REGION_NAME return step.subcloud.region_name @staticmethod diff --git a/distributedcloud/dcmanager/orchestrator/states/base.py b/distributedcloud/dcmanager/orchestrator/states/base.py index 7cc99538a..6e94ba49b 100644 --- a/distributedcloud/dcmanager/orchestrator/states/base.py +++ b/distributedcloud/dcmanager/orchestrator/states/base.py @@ -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 # @@ -11,14 +11,15 @@ from typing import Type from oslo_log import log as logging -from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.barbican import BarbicanClient from dccommon.drivers.openstack.fm import FmClient +from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.patching_v1 import PatchingClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.software_v1 import SoftwareClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon.drivers.openstack import vim +from dccommon import utils as cutils from dcmanager.common import consts from dcmanager.common import context from dcmanager.common import exceptions @@ -163,7 +164,7 @@ class BaseState(object, metaclass=abc.ABCMeta): """Get the region name for a strategy step""" if strategy_step.subcloud_id is None: # This is the SystemController. - return dccommon_consts.DEFAULT_REGION_NAME + return cutils.get_region_one_name() return strategy_step.subcloud.region_name @staticmethod @@ -171,13 +172,16 @@ class BaseState(object, metaclass=abc.ABCMeta): """Get the region name for a strategy step""" if strategy_step.subcloud_id is None: # This is the SystemController. - return dccommon_consts.DEFAULT_REGION_NAME + return cutils.get_region_one_name() return strategy_step.subcloud.name @staticmethod @lru_cache(maxsize=CLIENT_CACHE_SIZE) - def get_keystone_client(region_name: str = dccommon_consts.DEFAULT_REGION_NAME): + def get_keystone_client(region_name: str = None) -> KeystoneClient: """Construct a (cached) keystone client (and token)""" + if not region_name: + region_name = cutils.get_region_one_name() + try: return OpenStackDriver( region_name=region_name, @@ -205,20 +209,16 @@ class BaseState(object, metaclass=abc.ABCMeta): return FmClient(region_name, keystone_client.session, endpoint=endpoint) @lru_cache(maxsize=CLIENT_CACHE_SIZE) - def get_patching_client( - self, region_name: str = dccommon_consts.DEFAULT_REGION_NAME - ) -> PatchingClient: + def get_patching_client(self, region_name: str = None) -> PatchingClient: """Get the Patching client for the given region.""" keystone_client = self.get_keystone_client(region_name) - return PatchingClient(region_name, keystone_client.session) + return PatchingClient(keystone_client.region_name, keystone_client.session) @lru_cache(maxsize=CLIENT_CACHE_SIZE) - def get_software_client( - self, region_name: str = dccommon_consts.DEFAULT_REGION_NAME - ) -> SoftwareClient: + def get_software_client(self, region_name: str = None) -> SoftwareClient: """Get the Software client for the given region.""" keystone_client = self.get_keystone_client(region_name) - return SoftwareClient(keystone_client.session, region_name) + return SoftwareClient(keystone_client.session, keystone_client.region_name) @lru_cache(maxsize=CLIENT_CACHE_SIZE) def get_barbican_client(self, region_name: str) -> BarbicanClient: @@ -235,7 +235,7 @@ class BaseState(object, metaclass=abc.ABCMeta): @property def local_sysinv(self) -> SysinvClient: """Return the local Sysinv client.""" - return self.get_sysinv_client(dccommon_consts.DEFAULT_REGION_NAME) + return self.get_sysinv_client(cutils.get_region_one_name()) @property def subcloud_sysinv(self) -> SysinvClient: diff --git a/distributedcloud/dcmanager/orchestrator/states/firmware/importing_firmware.py b/distributedcloud/dcmanager/orchestrator/states/firmware/importing_firmware.py index 9d4f17c1e..b243af05f 100644 --- a/distributedcloud/dcmanager/orchestrator/states/firmware/importing_firmware.py +++ b/distributedcloud/dcmanager/orchestrator/states/firmware/importing_firmware.py @@ -1,12 +1,12 @@ # -# Copyright (c) 2020-2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2020-2022, 2024-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # import os -from dccommon import consts as dccommon_consts +from dccommon import utils as cutils from dcmanager.common import consts from dcmanager.orchestrator.states.base import BaseState from dcmanager.orchestrator.states.firmware import utils @@ -47,7 +47,7 @@ class ImportingFirmwareState(BaseState): # ============== query system controller images ============== system_controller_images = self.get_sysinv_client( - dccommon_consts.DEFAULT_REGION_NAME + cutils.get_region_one_name() ).get_device_images() # determine list of applied system controller images applied_system_controller_images = utils.filter_applied_images( diff --git a/distributedcloud/dcmanager/orchestrator/strategies/base.py b/distributedcloud/dcmanager/orchestrator/strategies/base.py index dcbe2e235..04e0ca97e 100644 --- a/distributedcloud/dcmanager/orchestrator/strategies/base.py +++ b/distributedcloud/dcmanager/orchestrator/strategies/base.py @@ -19,12 +19,13 @@ import abc from oslo_log import log as logging -from dccommon import consts as dccommon_consts +from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.patching_v1 import PatchingClient from dccommon.drivers.openstack.sdk_platform import OpenStackDriver from dccommon.drivers.openstack.software_v1 import SoftwareClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon.drivers.openstack import vim +from dccommon import utils as cutils from dcmanager.common import context from dcmanager.common import utils @@ -89,7 +90,7 @@ class BaseStrategy(object): """Subclass can override this method""" @staticmethod - def get_ks_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_ks_client(region_name: str = None) -> KeystoneClient: """This will get a cached keystone client (and token) throws an exception if keystone client cannot be initialized @@ -102,18 +103,27 @@ class BaseStrategy(object): return os_client.keystone_client @staticmethod - def get_vim_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_vim_client(region_name: str = None) -> vim.VimClient: + if not region_name: + region_name = cutils.get_region_one_name() + ks_client = BaseStrategy.get_ks_client(region_name) return vim.VimClient(region_name, ks_client.session) @staticmethod - def get_sysinv_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_sysinv_client(region_name: str = None) -> SysinvClient: + if not region_name: + region_name = cutils.get_region_one_name() + ks_client = BaseStrategy.get_ks_client(region_name) endpoint = ks_client.endpoint_cache.get_endpoint("sysinv") return SysinvClient(region_name, ks_client.session, endpoint=endpoint) @staticmethod - def get_software_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_software_client(region_name: str = None) -> SoftwareClient: + if not region_name: + region_name = cutils.get_region_one_name() + ks_client = BaseStrategy.get_ks_client(region_name) return SoftwareClient( ks_client.session, @@ -121,7 +131,10 @@ class BaseStrategy(object): ) @staticmethod - def get_patching_client(region_name=dccommon_consts.DEFAULT_REGION_NAME): + def get_patching_client(region_name: str = None) -> PatchingClient: + if not region_name: + region_name = cutils.get_region_one_name() + ks_client = BaseStrategy.get_ks_client(region_name) return PatchingClient(region_name, ks_client.session) diff --git a/distributedcloud/dcmanager/tests/unit/api/controllers/v1/test_sw_update_options.py b/distributedcloud/dcmanager/tests/unit/api/controllers/v1/test_sw_update_options.py index dd363b9a3..eaed6083d 100644 --- a/distributedcloud/dcmanager/tests/unit/api/controllers/v1/test_sw_update_options.py +++ b/distributedcloud/dcmanager/tests/unit/api/controllers/v1/test_sw_update_options.py @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Wind River Systems, Inc. +# Copyright (c) 2024-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -23,7 +23,7 @@ class SwUpdateOptionsMixin(object): def test_method_succeeds_with_subcloud_ref_as_default_region_name(self): """Test method succeeds with subcloud ref as default region name""" - self.url = f"{self.url}/{dccommon_consts.DEFAULT_REGION_NAME}" + self.url = f"{self.url}/{dccommon_consts.SYSTEM_CONTROLLER_NAME}" response = self._send_request() @@ -250,7 +250,7 @@ class TestSwUpdateOptionsPostUpdate(BaseTestSwUpdateOptionsPost, SwUpdateOptions ): """Test post update fails in default region with db api generic exception""" - self.url = f"{self.url}/{dccommon_consts.DEFAULT_REGION_NAME}" + self.url = f"{self.url}/{dccommon_consts.SYSTEM_CONTROLLER_NAME}" mock_db_api.side_effect = FakeException() @@ -293,7 +293,7 @@ class TestSwUpdateOptionsPostCreate(BaseTestSwUpdateOptionsPost, SwUpdateOptions if db_api.sw_update_opts_default_get(self.ctx) is not None: db_api.sw_update_opts_default_destroy(self.ctx) - self.url = f"{self.url}/{dccommon_consts.DEFAULT_REGION_NAME}" + self.url = f"{self.url}/{dccommon_consts.SYSTEM_CONTROLLER_NAME}" mock_db_api.side_effect = FakeException() @@ -334,13 +334,13 @@ class TestSwUpdateOptionsDelete( """Test delete succeeds with generic exception for default region name When a delete request is made for the default region name and there isn't a - sw_update_opts_default object in the database, a generic exception is catched - and the execution returnns + sw_update_opts_default object in the database, a generic exception is caught + and the execution returns """ db_api.sw_update_opts_default_destroy(self.ctx) - self.url = f"{self.url}/{dccommon_consts.DEFAULT_REGION_NAME}" + self.url = f"{self.url}/{dccommon_consts.SYSTEM_CONTROLLER_NAME}" response = self._send_request() diff --git a/distributedcloud/dcmanager/tests/unit/api/test_root_controller.py b/distributedcloud/dcmanager/tests/unit/api/test_root_controller.py index 534ed1455..d8678832d 100644 --- a/distributedcloud/dcmanager/tests/unit/api/test_root_controller.py +++ b/distributedcloud/dcmanager/tests/unit/api/test_root_controller.py @@ -1,5 +1,5 @@ # Copyright (c) 2015 Huawei Technologies Co., Ltd. -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -50,6 +50,11 @@ class DCManagerApiTest(DCManagerTestCase): config_fixture.set_config_dirs([]) self.CONF.set_override("auth_strategy", "noauth") + self.CONF.set_override( + "region_name", + uuidutils.generate_uuid().replace("-", ""), + group="keystone_authtoken", + ) self.app = self._make_app() diff --git a/distributedcloud/dcmanager/tests/unit/manager/test_subcloud_manager.py b/distributedcloud/dcmanager/tests/unit/manager/test_subcloud_manager.py index 0dfb3529b..70c9da8ab 100644 --- a/distributedcloud/dcmanager/tests/unit/manager/test_subcloud_manager.py +++ b/distributedcloud/dcmanager/tests/unit/manager/test_subcloud_manager.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -37,6 +37,7 @@ import mock import netaddr from oslo_concurrency import lockutils from oslo_utils import timeutils +from oslo_utils import uuidutils from tsconfig.tsconfig import SW_VERSION from dccommon import consts as dccommon_consts @@ -147,6 +148,7 @@ class FakeKeystoneClient(object): self.keystone_client = mock.MagicMock() self.session = mock.MagicMock() self.endpoint_cache = mock.MagicMock() + self.region_name = uuidutils.generate_uuid().replace("-", "") def get_enabled_users(self, id_only): if not id_only: @@ -4980,7 +4982,7 @@ class TestSubcloudEnrollment(BaseTestSubcloudManager): # Previous iso file must be cleaned up self.mock_os_remove.assert_called_once_with(self.iso_file) - # Makedirs shouldn't be invoked, given that prev iso exisited + # Makedirs shouldn't be invoked, given that prev iso existed self.mock_os_makedirs.assert_not_called() self.mock_log_subcloud_enrollment.info.assert_any_call( diff --git a/distributedcloud/dcorch/api/proxy/common/utils.py b/distributedcloud/dcorch/api/proxy/common/utils.py index 6f0a512e8..8a4f7cc0b 100644 --- a/distributedcloud/dcorch/api/proxy/common/utils.py +++ b/distributedcloud/dcorch/api/proxy/common/utils.py @@ -1,4 +1,4 @@ -# Copyright 2017-2024 Wind River +# Copyright 2017-2025 Wind River # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import psutil from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.sdk_platform import OpenStackDriver +from dccommon import utils as cutils from dcorch.common import consts LOG = logging.getLogger(__name__) @@ -148,10 +149,9 @@ def set_request_forward_environ(req, remote_host, remote_port): req.environ["HTTP_X_FORWARDED_FOR"] = req.environ["REMOTE_ADDR"] -def _get_fernet_keys(): +def _get_fernet_keys() -> list[str]: """Get fernet keys from sysinv.""" os_client = OpenStackDriver( - region_name=dccommon_consts.CLOUD_0, region_clients=("sysinv",), thread_name="proxy", ) @@ -164,14 +164,16 @@ def _get_fernet_keys(): ) as e: LOG.info( "get_fernet_keys: cloud {} is not reachable [{}]".format( - dccommon_consts.CLOUD_0, str(e) + cutils.get_region_one_name(), str(e) ) ) - OpenStackDriver.delete_region_clients(dccommon_consts.CLOUD_0) + OpenStackDriver.delete_region_clients(cutils.get_region_one_name()) return None except (AttributeError, TypeError) as e: LOG.info("get_fernet_keys error {}".format(e)) - OpenStackDriver.delete_region_clients(dccommon_consts.CLOUD_0, clear_token=True) + OpenStackDriver.delete_region_clients( + cutils.get_region_one_name(), clear_token=True + ) return None except Exception as e: LOG.exception(e) diff --git a/distributedcloud/dcorch/drivers/openstack/sdk.py b/distributedcloud/dcorch/drivers/openstack/sdk.py index 1ede8a529..2f6a7d425 100644 --- a/distributedcloud/dcorch/drivers/openstack/sdk.py +++ b/distributedcloud/dcorch/drivers/openstack/sdk.py @@ -1,5 +1,5 @@ # Copyright 2016 Ericsson AB -# Copyright (c) 2021, 2024 Wind River Systems, Inc. +# Copyright (c) 2021, 2024-2025 Wind River Systems, Inc. # 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 @@ -26,6 +26,7 @@ from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.fm import FmClient from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient +from dccommon import utils as cutils # Gap, in seconds, to determine whether the given token is about to expire STALE_TOKEN_DURATION = 60 @@ -39,10 +40,12 @@ class OpenStackDriver(object): _identity_tokens = {} @lockutils.synchronized("dcorch-openstackdriver") - def __init__(self, region_name=dccommon_consts.VIRTUAL_MASTER_CLOUD, auth_url=None): - # Check if objects are cached and try to use those + def __init__( + self, region_name: str = dccommon_consts.SYSTEM_CONTROLLER_NAME, auth_url=None + ): self.region_name = region_name + # Check if objects are cached and try to use those if ( region_name in OpenStackDriver._identity_tokens and (region_name in OpenStackDriver.os_clients_dict) @@ -256,9 +259,9 @@ class OpenStackDriver(object): # If endpoint filter is not used for the project, then # return all regions region_lists = KeystoneClient().endpoint_cache.get_all_regions() - # nova, cinder, and neutron have no endpoints in consts.CLOUD_0 - if dccommon_consts.CLOUD_0 in region_lists: - region_lists.remove(dccommon_consts.CLOUD_0) + # nova, cinder, and neutron have no endpoints in the local region + if cutils.get_region_one_name() in region_lists: + region_lists.remove(cutils.get_region_one_name()) return region_lists except Exception as exception: LOG.error("Error Occurred: %s", str(exception)) diff --git a/distributedcloud/dcorch/engine/fernet_key_manager.py b/distributedcloud/dcorch/engine/fernet_key_manager.py index 710c63bef..f5c9252a3 100644 --- a/distributedcloud/dcorch/engine/fernet_key_manager.py +++ b/distributedcloud/dcorch/engine/fernet_key_manager.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2018-2022, 2024-2025 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ from dccommon import consts as dccommon_consts from dccommon.drivers.openstack.keystone_v3 import KeystoneClient from dccommon.drivers.openstack.sysinv_v1 import SysinvClient from dccommon.endpoint_cache import EndpointCache -from dccommon.utils import build_subcloud_endpoint +from dccommon import utils as cutils from dcorch.common import consts from dcorch.common import context from dcorch.common import exceptions @@ -72,7 +72,9 @@ class FernetKeyManager(manager.Manager): def _schedule_work(self, operation_type, subcloud=None): keys = self._get_master_keys() if not keys: - LOG.info(_("No fernet keys returned from %s") % dccommon_consts.CLOUD_0) + LOG.info( + _("No fernet keys returned from %s") % cutils.get_region_one_name() + ) return try: resource_info = FernetKeyManager.to_resource_info(keys) @@ -95,12 +97,13 @@ class FernetKeyManager(manager.Manager): def _get_master_keys(): """get the keys from the local fernet key repo""" keys = [] + local_region = cutils.get_region_one_name() try: # No cached client is required as it is called during the initial # sync and after weekly key rotation - ks_client = KeystoneClient(dccommon_consts.CLOUD_0) + ks_client = KeystoneClient(local_region) sysinv_client = SysinvClient( - dccommon_consts.CLOUD_0, + local_region, ks_client.session, endpoint=ks_client.endpoint_cache.get_endpoint("sysinv"), ) @@ -111,8 +114,7 @@ class FernetKeyManager(manager.Manager): exceptions.TimeOut, ): LOG.exception( - _("Retrieving the fernet keys from %s timeout") - % dccommon_consts.CLOUD_0 + _("Retrieving the fernet keys from %s timeout") % local_region ) except Exception as e: LOG.exception(_("Fail to retrieve the master fernet keys: %s") % str(e)) @@ -136,7 +138,9 @@ class FernetKeyManager(manager.Manager): def distribute_keys(subcloud_name, management_ip): keys = FernetKeyManager._get_master_keys() if not keys: - LOG.info(_("No fernet keys returned from %s") % dccommon_consts.CLOUD_0) + LOG.info( + _("No fernet keys returned from %s") % cutils.get_region_one_name() + ) return resource_info = FernetKeyManager.to_resource_info(keys) key_list = FernetKeyManager.from_resource_info(resource_info) @@ -145,7 +149,9 @@ class FernetKeyManager(manager.Manager): @staticmethod def update_fernet_repo(subcloud_name, management_ip, key_list=None): try: - keystone_endpoint = build_subcloud_endpoint(management_ip, "keystone") + keystone_endpoint = cutils.build_subcloud_endpoint( + management_ip, "keystone" + ) admin_session = EndpointCache.get_admin_session( keystone_endpoint, CONF.endpoint_cache.username, @@ -157,7 +163,7 @@ class FernetKeyManager(manager.Manager): sysinv_client = SysinvClient( region=subcloud_name, session=admin_session, - endpoint=build_subcloud_endpoint(management_ip, "sysinv"), + endpoint=cutils.build_subcloud_endpoint(management_ip, "sysinv"), ) sysinv_client.post_fernet_repo(key_list) except ( diff --git a/distributedcloud/dcorch/engine/quota_manager.py b/distributedcloud/dcorch/engine/quota_manager.py index d6cb2153e..2ffa4e81e 100644 --- a/distributedcloud/dcorch/engine/quota_manager.py +++ b/distributedcloud/dcorch/engine/quota_manager.py @@ -1,5 +1,5 @@ # Copyright 2016 Ericsson AB -# Copyright (c) 2018-2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2018-2022, 2024-2025 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -114,7 +114,7 @@ class QuotaManager(manager.Manager): def get_projects_users_with_modified_quotas(self): # get the list of project/user tuples that have modified quotas project_user_list = set([]) - os_client = sdk.OpenStackDriver(dccommon_consts.VIRTUAL_MASTER_CLOUD) + os_client = sdk.OpenStackDriver() try: quotas = os_client.nova_client.nova_client.quotas.list() project_user_quotas = quotas["project_user_quotas"] @@ -306,7 +306,7 @@ class QuotaManager(manager.Manager): # are managed by dcorch so delete them from all regions except # the master one. for region in regions_usage_dict_copy: - if region == dccommon_consts.VIRTUAL_MASTER_CLOUD: + if region == dccommon_consts.SYSTEM_CONTROLLER_NAME: continue for quota in consts.QUOTAS_FOR_MANAGED_RESOURCES: regions_usage_dict_copy[region].pop(quota, None) @@ -362,7 +362,7 @@ class QuotaManager(manager.Manager): # Remove the master region from the list. Its quotas should already # be up to date for managed resources. - region_lists.remove(dccommon_consts.VIRTUAL_MASTER_CLOUD) + region_lists.remove(dccommon_consts.SYSTEM_CONTROLLER_NAME) # (NOTE: knasim-wrs): The Master Cloud's Project ID and User ID # dont mean anything for the subcloud, so we need to first resolve @@ -421,7 +421,7 @@ class QuotaManager(manager.Manager): # Return quota limits in the master cloud. These are the overall # quota limits for the whole cloud. return self.get_tenant_quota_limits_region( - project_id, user_id, dccommon_consts.VIRTUAL_MASTER_CLOUD + project_id, user_id, dccommon_consts.SYSTEM_CONTROLLER_NAME ) def get_tenant_quota_usage_per_region(self, project_id, user_id): diff --git a/distributedcloud/dcorch/engine/sync_services/compute.py b/distributedcloud/dcorch/engine/sync_services/compute.py index a23251734..569f7754d 100644 --- a/distributedcloud/dcorch/engine/sync_services/compute.py +++ b/distributedcloud/dcorch/engine/sync_services/compute.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2018, 2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2017-2018, 2022, 2024-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -80,7 +80,7 @@ class ComputeSyncThread(SyncThread): "2.38", session=self.admin_session, endpoint_type=dccommon_consts.KS_ENDPOINT_INTERNAL, - region_name=dccommon_consts.VIRTUAL_MASTER_CLOUD, + region_name=dccommon_consts.SYSTEM_CONTROLLER_NAME, ) self.initialize_sc_clients() diff --git a/distributedcloud/dcorch/engine/sync_services/identity.py b/distributedcloud/dcorch/engine/sync_services/identity.py index fed065c92..47a343514 100644 --- a/distributedcloud/dcorch/engine/sync_services/identity.py +++ b/distributedcloud/dcorch/engine/sync_services/identity.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2018-2022, 2024-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -463,7 +463,7 @@ class IdentitySyncThread(SyncThread): if not m_users: LOG.error( - "No users returned from {}".format(dccommon_consts.VIRTUAL_MASTER_CLOUD) + f"No users returned from {dccommon_consts.SYSTEM_CONTROLLER_NAME}" ) raise exceptions.SyncRequestFailed @@ -483,9 +483,7 @@ class IdentitySyncThread(SyncThread): if not m_groups: LOG.info( - "No groups returned from {}".format( - dccommon_consts.VIRTUAL_MASTER_CLOUD - ) + f"No groups returned from {dccommon_consts.SYSTEM_CONTROLLER_NAME}" ) # get groups from the subcloud @@ -504,9 +502,7 @@ class IdentitySyncThread(SyncThread): if not m_projects: LOG.error( - "No projects returned from {}".format( - dccommon_consts.VIRTUAL_MASTER_CLOUD - ) + f"No projects returned from {dccommon_consts.SYSTEM_CONTROLLER_NAME}" ) raise exceptions.SyncRequestFailed @@ -526,7 +522,7 @@ class IdentitySyncThread(SyncThread): if not m_roles: LOG.error( - "No roles returned from {}".format(dccommon_consts.VIRTUAL_MASTER_CLOUD) + f"No roles returned from {dccommon_consts.SYSTEM_CONTROLLER_NAME}" ) raise exceptions.SyncRequestFailed @@ -2021,7 +2017,7 @@ class IdentitySyncThread(SyncThread): else: continue - # The id of a Role Assigment is: + # The id of a Role Assignment is: # projectID_userID_roleID assignment_dict["id"] = "{}_{}_{}".format(project_id, actor_id, role_id) @@ -2299,7 +2295,7 @@ class IdentitySyncThread(SyncThread): except dbsync_exceptions.Unauthorized as e: LOG.info( "Get master resource [{}] request failed for {}: {}.".format( - resource_type, dccommon_consts.VIRTUAL_MASTER_CLOUD, str(e) + resource_type, dccommon_consts.SYSTEM_CONTROLLER_NAME, str(e) ), extra=self.log_extra, ) @@ -2320,7 +2316,7 @@ class IdentitySyncThread(SyncThread): except keystone_exceptions.Unauthorized as e: LOG.info( "Get master resource [{}] request failed for {}: {}.".format( - resource_type, dccommon_consts.VIRTUAL_MASTER_CLOUD, str(e) + resource_type, dccommon_consts.SYSTEM_CONTROLLER_NAME, str(e) ), extra=self.log_extra, ) diff --git a/distributedcloud/dcorch/engine/sync_services/network.py b/distributedcloud/dcorch/engine/sync_services/network.py index 5468854ba..f48b44b14 100644 --- a/distributedcloud/dcorch/engine/sync_services/network.py +++ b/distributedcloud/dcorch/engine/sync_services/network.py @@ -1,4 +1,4 @@ -# Copyright 2017-2018, 2022, 2024 Wind River +# Copyright 2017-2018, 2022, 2024-2025 Wind River # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -79,7 +79,7 @@ class NetworkSyncThread(SyncThread): "2.0", session=self.admin_session, endpoint_type=dccommon_consts.KS_ENDPOINT_INTERNAL, - region_name=dccommon_consts.VIRTUAL_MASTER_CLOUD, + region_name=dccommon_consts.SYSTEM_CONTROLLER_NAME, ) self.initialize_sc_clients() diff --git a/distributedcloud/dcorch/engine/sync_services/sysinv.py b/distributedcloud/dcorch/engine/sync_services/sysinv.py index 727b15188..cec60e055 100644 --- a/distributedcloud/dcorch/engine/sync_services/sysinv.py +++ b/distributedcloud/dcorch/engine/sync_services/sysinv.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, 2024 Wind River Systems, Inc. +# Copyright (c) 2017-2022, 2024-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -596,7 +596,7 @@ class SysinvSyncThread(SyncThread): super().post_audit() OpenStackDriver.delete_region_clients_for_thread(self.region_name, "audit") OpenStackDriver.delete_region_clients_for_thread( - dccommon_consts.CLOUD_0, "audit" + dccommon_utils.get_region_one_name(), "audit" ) @classmethod diff --git a/distributedcloud/dcorch/engine/sync_services/volume.py b/distributedcloud/dcorch/engine/sync_services/volume.py index b505658f9..0a2ea37b2 100644 --- a/distributedcloud/dcorch/engine/sync_services/volume.py +++ b/distributedcloud/dcorch/engine/sync_services/volume.py @@ -1,4 +1,4 @@ -# Copyright 2017-2018, 2024 Wind River +# Copyright 2017-2018, 2024-2025 Wind River # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ class VolumeSyncThread(SyncThread): "3.0", session=self.admin_session, endpoint_type=dccommon_consts.KS_ENDPOINT_INTERNAL, - region_name=dccommon_consts.VIRTUAL_MASTER_CLOUD, + region_name=dccommon_consts.SYSTEM_CONTROLLER_NAME, ) self.initialize_sc_clients() diff --git a/distributedcloud/dcorch/engine/sync_thread.py b/distributedcloud/dcorch/engine/sync_thread.py index e6c213d7a..47a01d5e6 100644 --- a/distributedcloud/dcorch/engine/sync_thread.py +++ b/distributedcloud/dcorch/engine/sync_thread.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2024 Wind River Systems, Inc. +# Copyright (c) 2017-2025 Wind River Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +26,7 @@ from oslo_utils import timeutils from dccommon import consts as dccommon_consts from dccommon.drivers.openstack import sdk_platform as sdk from dccommon.endpoint_cache import EndpointCache -from dccommon.utils import build_subcloud_endpoint +from dccommon import utils as cutils from dcdbsync.dbsyncclient import client as dbsyncclient from dcmanager.rpc import client as dcmanager_rpc_client from dcorch.common import consts @@ -72,13 +72,11 @@ def get_master_os_client(region_clients=None): # cached in the openstack driver, because we don't want to hold the admin # sessions for the subclouds. try: - os_client = sdk.OpenStackDriver( - region_name=dccommon_consts.CLOUD_0, region_clients=region_clients - ) + os_client = sdk.OpenStackDriver(region_clients=region_clients) except Exception as e: LOG.error( "Failed to get os_client for " - f"{dccommon_consts.CLOUD_0}/{region_clients}: {e}." + f"{cutils.get_region_one_name()}/{region_clients}: {e}." ) raise e return os_client @@ -114,7 +112,7 @@ class SyncThread(object): self.engine_id = engine_id self.ctxt = context.get_admin_context() self.sync_handler_map = {} - self.master_region_name = dccommon_consts.CLOUD_0 + self.master_region_name = cutils.get_region_one_name() self.audit_resources = [] self.log_extra = {"instance": self.subcloud_name + ": "} @@ -185,13 +183,13 @@ class SyncThread(object): # keystone client self.ks_client = keystoneclient.Client( - session=self.admin_session, region_name=dccommon_consts.CLOUD_0 + session=self.admin_session, region_name=cutils.get_region_one_name() ) # dcdbsync client self.dbs_client = dbsyncclient.Client( endpoint_type=consts.DBS_ENDPOINT_INTERNAL, session=self.admin_session, - region_name=dccommon_consts.CLOUD_0, + region_name=cutils.get_region_one_name(), ) def initialize_sc_clients(self): @@ -201,7 +199,9 @@ class SyncThread(object): if not self.sc_admin_session: # Subclouds will use token from the Subcloud specific Keystone, # so define a session against that subcloud's keystone endpoint - self.sc_auth_url = build_subcloud_endpoint(self.management_ip, "keystone") + self.sc_auth_url = cutils.build_subcloud_endpoint( + self.management_ip, "keystone" + ) LOG.debug( f"Built sc_auth_url {self.sc_auth_url} for subcloud " f"{self.subcloud_name}"