mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-04-14 16:50:04 +00:00
fix(api): update database routing logic in MainRouter (#9080)
This commit is contained in:
committed by
GitHub
parent
46bf8e0fef
commit
aa8be0b2fe
@@ -15,6 +15,7 @@ All notable changes to the **Prowler API** are documented in this file.
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- `/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)
|
- `/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)
|
||||||
|
- 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)
|
||||||
|
|
||||||
## [1.14.0] (Prowler 5.13.0)
|
## [1.14.0] (Prowler 5.13.0)
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ class MainRouter:
|
|||||||
return db == self.admin_db
|
return db == self.admin_db
|
||||||
|
|
||||||
def allow_relation(self, obj1, obj2, **hints): # noqa: F841
|
def allow_relation(self, obj1, obj2, **hints): # noqa: F841
|
||||||
# Allow relations if both objects are in either "default" or "admin" db connectors
|
# Allow relations when both objects originate from allowed connectors
|
||||||
if {obj1._state.db, obj2._state.db} <= {self.default_db, self.admin_db}:
|
allowed_dbs = {self.default_db, self.admin_db, self.replica_db}
|
||||||
|
if {obj1._state.db, obj2._state.db} <= allowed_dbs:
|
||||||
return True
|
return True
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from celery.utils.log import get_task_logger
|
|||||||
from config.django.base import DJANGO_FINDINGS_BATCH_SIZE
|
from config.django.base import DJANGO_FINDINGS_BATCH_SIZE
|
||||||
from tasks.utils import batched
|
from tasks.utils import batched
|
||||||
|
|
||||||
from api.db_router import READ_REPLICA_ALIAS
|
from api.db_router import READ_REPLICA_ALIAS, MainRouter
|
||||||
from api.db_utils import rls_transaction
|
from api.db_utils import rls_transaction
|
||||||
from api.models import Finding, Integration, Provider
|
from api.models import Finding, Integration, Provider
|
||||||
from api.utils import initialize_prowler_integration, initialize_prowler_provider
|
from api.utils import initialize_prowler_integration, initialize_prowler_provider
|
||||||
@@ -179,7 +179,7 @@ def get_security_hub_client_from_integration(
|
|||||||
if the connection was successful and the SecurityHub client or connection object.
|
if the connection was successful and the SecurityHub client or connection object.
|
||||||
"""
|
"""
|
||||||
# Get the provider associated with this integration
|
# Get the provider associated with this integration
|
||||||
with rls_transaction(tenant_id):
|
with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
|
||||||
provider_relationship = integration.integrationproviderrelationship_set.first()
|
provider_relationship = integration.integrationproviderrelationship_set.first()
|
||||||
if not provider_relationship:
|
if not provider_relationship:
|
||||||
return Connection(
|
return Connection(
|
||||||
@@ -208,7 +208,7 @@ def get_security_hub_client_from_integration(
|
|||||||
regions_status[region] = region in connection.enabled_regions
|
regions_status[region] = region in connection.enabled_regions
|
||||||
|
|
||||||
# Save regions information in the integration configuration
|
# Save regions information in the integration configuration
|
||||||
with rls_transaction(tenant_id):
|
with rls_transaction(tenant_id, using=MainRouter.default_db):
|
||||||
integration.configuration["regions"] = regions_status
|
integration.configuration["regions"] = regions_status
|
||||||
integration.save()
|
integration.save()
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ def get_security_hub_client_from_integration(
|
|||||||
return True, security_hub
|
return True, security_hub
|
||||||
else:
|
else:
|
||||||
# Reset regions information if connection fails
|
# Reset regions information if connection fails
|
||||||
with rls_transaction(tenant_id):
|
with rls_transaction(tenant_id, using=MainRouter.default_db):
|
||||||
integration.configuration["regions"] = {}
|
integration.configuration["regions"] = {}
|
||||||
integration.save()
|
integration.save()
|
||||||
|
|
||||||
@@ -334,8 +334,11 @@ def upload_security_hub_integration(
|
|||||||
f"Security Hub connection failed for integration {integration.id}: "
|
f"Security Hub connection failed for integration {integration.id}: "
|
||||||
f"{security_hub.error}"
|
f"{security_hub.error}"
|
||||||
)
|
)
|
||||||
integration.connected = False
|
with rls_transaction(
|
||||||
integration.save()
|
tenant_id, using=MainRouter.default_db
|
||||||
|
):
|
||||||
|
integration.connected = False
|
||||||
|
integration.save()
|
||||||
break # Skip this integration
|
break # Skip this integration
|
||||||
|
|
||||||
security_hub_client = security_hub
|
security_hub_client = security_hub
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from tasks.jobs.integrations import (
|
|||||||
upload_security_hub_integration,
|
upload_security_hub_integration,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from api.db_router import READ_REPLICA_ALIAS, MainRouter
|
||||||
from api.models import Integration
|
from api.models import Integration
|
||||||
from api.utils import prowler_integration_connection_test
|
from api.utils import prowler_integration_connection_test
|
||||||
from prowler.providers.aws.lib.security_hub.security_hub import SecurityHubConnection
|
from prowler.providers.aws.lib.security_hub.security_hub import SecurityHubConnection
|
||||||
@@ -880,7 +881,8 @@ class TestSecurityHubIntegrationUploads:
|
|||||||
# Verify RLS transaction was used correctly
|
# Verify RLS transaction was used correctly
|
||||||
# Should be called twice: once for getting provider info, once for resetting regions
|
# Should be called twice: once for getting provider info, once for resetting regions
|
||||||
assert mock_rls.call_count == 2
|
assert mock_rls.call_count == 2
|
||||||
mock_rls.assert_any_call(tenant_id)
|
mock_rls.assert_any_call(tenant_id, using=READ_REPLICA_ALIAS)
|
||||||
|
mock_rls.assert_any_call(tenant_id, using=MainRouter.default_db)
|
||||||
|
|
||||||
# Verify test_connection was called with integration credentials (not provider's)
|
# Verify test_connection was called with integration credentials (not provider's)
|
||||||
mock_test_connection.assert_called_once_with(
|
mock_test_connection.assert_called_once_with(
|
||||||
|
|||||||
Reference in New Issue
Block a user