From 8fcb8e53b7b0fd455584f3ea72499be59ce40b07 Mon Sep 17 00:00:00 2001 From: "Hugo P.Brito" Date: Thu, 20 Aug 2026 13:13:55 +0100 Subject: [PATCH] fix(huaweicloud): preserve FunctionGraph region attribution - Carry regional client keys through function discovery - Cover regionless SDK clients with a regression test - Document FunctionGraph initialization behavior --- .../functiongraph/functiongraph_service.py | 13 ++++++++--- .../huaweicloud_functiongraph_service_test.py | 22 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/prowler/providers/huaweicloud/services/functiongraph/functiongraph_service.py b/prowler/providers/huaweicloud/services/functiongraph/functiongraph_service.py index afde9bf567..b083c7f3de 100644 --- a/prowler/providers/huaweicloud/services/functiongraph/functiongraph_service.py +++ b/prowler/providers/huaweicloud/services/functiongraph/functiongraph_service.py @@ -15,6 +15,11 @@ class FunctionGraph(HuaweiCloudService): """ def __init__(self, provider): + """Initialize FunctionGraph and discover functions in enabled regions. + + Args: + provider: The Huawei Cloud provider used to create regional clients. + """ super().__init__(__class__.__name__, provider) self.functions: List[FunctionGraphFunction] = [] @@ -23,7 +28,9 @@ class FunctionGraph(HuaweiCloudService): self._load_mock_data() return - self.__threading_call__(self._list_functions) + self.__threading_call__( + self._list_functions, iterator=self.regional_clients.items() + ) def _load_mock_data(self): """Load mock data for testing.""" @@ -51,9 +58,9 @@ class FunctionGraph(HuaweiCloudService): ), ] - def _list_functions(self, regional_client): + def _list_functions(self, regional_client_item): """List every FunctionGraph function in one region.""" - region = getattr(regional_client, "region", "unknown") + region, regional_client = regional_client_item logger.info(f"FunctionGraph - Listing Functions in {region}...") discovered_functions = [] marker = None diff --git a/tests/providers/huaweicloud/services/functiongraph/huaweicloud_functiongraph_service_test.py b/tests/providers/huaweicloud/services/functiongraph/huaweicloud_functiongraph_service_test.py index c82d414605..ef397e3386 100644 --- a/tests/providers/huaweicloud/services/functiongraph/huaweicloud_functiongraph_service_test.py +++ b/tests/providers/huaweicloud/services/functiongraph/huaweicloud_functiongraph_service_test.py @@ -11,9 +11,18 @@ from tests.providers.huaweicloud.huaweicloud_fixtures import ( class TestFunctionGraphService: def test_real_session_lists_functions(self): - regional_client = mock.MagicMock(region="eu-west-101") + function = SimpleNamespace( + resource_id="resource-1", + func_urn="urn:fss:eu-west-101:project-1:function:default:first:latest", + func_name="first", + runtime="Python3.9", + timeout=30, + memory_size=128, + func_vpc_id=None, + ) + regional_client = SimpleNamespace(list_functions=mock.MagicMock()) regional_client.list_functions.return_value = SimpleNamespace( - functions=[], next_marker=None + functions=[function], next_marker=None ) provider = set_mocked_huaweicloud_provider() provider.session = SimpleNamespace(client=mock.MagicMock()) @@ -24,7 +33,8 @@ class TestFunctionGraphService: service = FunctionGraph(provider) - assert service.functions == [] + assert len(service.functions) == 1 + assert service.functions[0].region == "eu-west-101" regional_client.list_functions.assert_called_once() def test_lists_every_page_and_maps_sdk_fields(self): @@ -58,7 +68,7 @@ class TestFunctionGraphService: side_effect=regional_client.list_functions.side_effect ) - service._list_functions(regional_client) + service._list_functions(("eu-west-101", regional_client)) assert [function.id for function in service.functions] == [ "resource-1", @@ -98,7 +108,7 @@ class TestFunctionGraphService: ] ) - service._list_functions(regional_client) + service._list_functions(("eu-west-101", regional_client)) assert service.functions == [] @@ -123,7 +133,7 @@ class TestFunctionGraphService: ] ) - service._list_functions(regional_client) + service._list_functions(("eu-west-101", regional_client)) assert [item.id for item in service.functions] == ["resource-1"] assert service._call_with_retries.call_count == 2