Skip to content

Commit aa8be0b

Browse files
authored
fix(api): update database routing logic in MainRouter (#9080)
1 parent 46bf8e0 commit aa8be0b

File tree

4 files changed

+16
-9
lines changed

4 files changed

+16
-9
lines changed

api/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ All notable changes to the **Prowler API** are documented in this file.
1515

1616
### Fixed
1717
- `/api/v1/overviews/providers` collapses data by provider type so the UI receives a single aggregated record per cloud family even when multiple accounts exist [(#9053)](https://github.com/prowler-cloud/prowler/pull/9053)
18+
- Security Hub integrations stop failing when they read relationships via the replica by allowing replica relations and saving updates through the primary [(#9080)](https://github.com/prowler-cloud/prowler/pull/9080)
1819

1920
## [1.14.0] (Prowler 5.13.0)
2021

api/src/backend/api/db_router.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ def allow_migrate(self, db, app_label, model_name=None, **hints): # noqa: F841
4848
return db == self.admin_db
4949

5050
def allow_relation(self, obj1, obj2, **hints): # noqa: F841
51-
# Allow relations if both objects are in either "default" or "admin" db connectors
52-
if {obj1._state.db, obj2._state.db} <= {self.default_db, self.admin_db}:
51+
# Allow relations when both objects originate from allowed connectors
52+
allowed_dbs = {self.default_db, self.admin_db, self.replica_db}
53+
if {obj1._state.db, obj2._state.db} <= allowed_dbs:
5354
return True
5455
return None
5556

api/src/backend/tasks/jobs/integrations.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from config.django.base import DJANGO_FINDINGS_BATCH_SIZE
66
from tasks.utils import batched
77

8-
from api.db_router import READ_REPLICA_ALIAS
8+
from api.db_router import READ_REPLICA_ALIAS, MainRouter
99
from api.db_utils import rls_transaction
1010
from api.models import Finding, Integration, Provider
1111
from api.utils import initialize_prowler_integration, initialize_prowler_provider
@@ -179,7 +179,7 @@ def get_security_hub_client_from_integration(
179179
if the connection was successful and the SecurityHub client or connection object.
180180
"""
181181
# Get the provider associated with this integration
182-
with rls_transaction(tenant_id):
182+
with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
183183
provider_relationship = integration.integrationproviderrelationship_set.first()
184184
if not provider_relationship:
185185
return Connection(
@@ -208,7 +208,7 @@ def get_security_hub_client_from_integration(
208208
regions_status[region] = region in connection.enabled_regions
209209

210210
# Save regions information in the integration configuration
211-
with rls_transaction(tenant_id):
211+
with rls_transaction(tenant_id, using=MainRouter.default_db):
212212
integration.configuration["regions"] = regions_status
213213
integration.save()
214214

@@ -223,7 +223,7 @@ def get_security_hub_client_from_integration(
223223
return True, security_hub
224224
else:
225225
# Reset regions information if connection fails
226-
with rls_transaction(tenant_id):
226+
with rls_transaction(tenant_id, using=MainRouter.default_db):
227227
integration.configuration["regions"] = {}
228228
integration.save()
229229

@@ -334,8 +334,11 @@ def upload_security_hub_integration(
334334
f"Security Hub connection failed for integration {integration.id}: "
335335
f"{security_hub.error}"
336336
)
337-
integration.connected = False
338-
integration.save()
337+
with rls_transaction(
338+
tenant_id, using=MainRouter.default_db
339+
):
340+
integration.connected = False
341+
integration.save()
339342
break # Skip this integration
340343

341344
security_hub_client = security_hub

api/src/backend/tasks/tests/test_integrations.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
upload_security_hub_integration,
1010
)
1111

12+
from api.db_router import READ_REPLICA_ALIAS, MainRouter
1213
from api.models import Integration
1314
from api.utils import prowler_integration_connection_test
1415
from prowler.providers.aws.lib.security_hub.security_hub import SecurityHubConnection
@@ -880,7 +881,8 @@ def test_get_security_hub_client_from_integration_failure_clears_existing_region
880881
# Verify RLS transaction was used correctly
881882
# Should be called twice: once for getting provider info, once for resetting regions
882883
assert mock_rls.call_count == 2
883-
mock_rls.assert_any_call(tenant_id)
884+
mock_rls.assert_any_call(tenant_id, using=READ_REPLICA_ALIAS)
885+
mock_rls.assert_any_call(tenant_id, using=MainRouter.default_db)
884886

885887
# Verify test_connection was called with integration credentials (not provider's)
886888
mock_test_connection.assert_called_once_with(

0 commit comments

Comments
 (0)