Skip to content

fix(azure/postgresql): isolate per-server collection failures#11595

Open
vahidg wants to merge 3 commits into
prowler-cloud:masterfrom
vahidg:fix/azure-postgresql-server-collection-resilience
Open

fix(azure/postgresql): isolate per-server collection failures#11595
vahidg wants to merge 3 commits into
prowler-cloud:masterfrom
vahidg:fix/azure-postgresql-server-collection-resilience

Conversation

@vahidg

@vahidg vahidg commented Jun 15, 2026

Copy link
Copy Markdown

Context

While scanning an Azure tenant I noticed the Azure PostgreSQL service silently under-reported flexible servers: a subscription with two flexible servers (...-dev and ...-prd) only ever produced findings for one of them.

Root cause: PostgreSQL._get_flexible_servers() iterates the servers of a subscription, but the per-server collection runs inside a single subscription-level try/except. If any per-server call raises, the handler catches it, logs at ERROR, and abandons every server not yet processed — so one bad server discards the rest of the subscription.

In this case the trigger was PostgreSQL 16+, where the connection_throttle.enable server parameter no longer exists. _get_connection_throttling() therefore raised ResourceNotFoundError (ConfigurationNotExists), which bubbled up and dropped the remaining servers. It was invisible in normal use because that ERROR log is hidden from the console at the default log level.

No linked issue — happy to open one if preferred.

Description

  • Wrap each server's collection in its own try/except so a single server's failure no longer aborts collection of the other servers in the subscription (the subscription-level handler around servers.list() is kept).
  • Make _get_connection_throttling() tolerate the missing parameter and return None (mirroring the existing _get_log_retention_days()), so PostgreSQL 16+ servers are still collected. With connection_throttling=None the postgresql_flexible_server_connection_throttling_on check reports FAIL, matching its existing semantics.

Adds regression tests for both the missing-config case and a hard per-server failure.

Steps to review

  1. Read _get_flexible_servers() — per-server try/except now wraps the body; the subscription-level handler remains for servers.list().
  2. Read _get_connection_throttling() — now returns None on exception, consistent with _get_log_retention_days().
  3. Run the tests:
    pytest tests/providers/azure/services/postgresql/ -q
    
    • test_missing_connection_throttle_config_still_collects_server — both servers collected; the PG 16+ server gets connection_throttling=None.
    • test_one_server_hard_failure_does_not_drop_others — a server that fails on servers.get is skipped without dropping the rest.

This is a bugfix and is likely a backport candidate.

Checklist

  • Review if the code is being covered by tests.
  • Review if code is being documented following the style guide.
  • Review if backport is needed. (Looks applicable — deferring to maintainers.)
  • Review if is needed to change the Readme.md (not applicable).
  • Ensure new entries are added to CHANGELOG.md, if applicable.

SDK/CLI

  • Are there new checks included in this PR? No

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Summary by CodeRabbit

  • Bug Fixes
    • Azure PostgreSQL flexible server collection is now resilient: failures for an individual server no longer stop collection of the remaining servers in the same subscription.
    • Updated behavior for PostgreSQL 16+ connection throttling configuration so missing/unsupported connection_throttle.enable is treated as not enabled (no interruption).

Collecting one PostgreSQL flexible server could abort collection of every
remaining server in the subscription. The per-server work ran inside a single
subscription-level try/except, so one failing call discarded all servers not
yet processed (the failing one and the rest).

This happened on PostgreSQL 16+, where the `connection_throttle.enable` server
parameter no longer exists: `_get_connection_throttling` raised
ConfigurationNotExists, which bubbled up and dropped the remaining servers in
the subscription. It was silent because the error is logged at ERROR level,
which is hidden from the console by default.

- Wrap each server's collection in its own try/except so one server's failure
  no longer aborts the others in the subscription.
- Make `_get_connection_throttling` tolerate the missing parameter (return
  None, like `_get_log_retention_days`), so PostgreSQL 16+ servers are still
  collected.

Adds regression tests for the missing-config case and a hard per-server failure.
@vahidg vahidg requested a review from a team as a code owner June 15, 2026 13:26
@github-actions github-actions Bot added the provider/azure Issues/PRs related with the Azure provider label Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

PostgreSQL._get_flexible_servers() and _get_connection_throttling() are updated to wrap per-server processing in try/except blocks, isolating individual server failures so subscription-level collection continues. Two new resilience tests and a changelog entry accompany the changes.

Changes

Azure PostgreSQL flexible server error isolation

Layer / File(s) Summary
Connection throttling error handling and Server dataclass type update
prowler/providers/azure/services/postgresql/postgresql_service.py
_get_connection_throttling() wraps the configurations.get lookup in try/except and returns None instead of raising when connection_throttle.enable is absent or unsupported (removed in PostgreSQL 16+ flexible servers). Server.connection_throttling field type changes from str to str | None to accept the None return value.
Flexible server enumeration per-server error isolation
prowler/providers/azure/services/postgresql/postgresql_service.py
_get_flexible_servers() wraps each server's resource-group lookup, server-details fetch, configuration extraction, and Server construction in an inner try/except that logs per-server errors (including subscription id, exception class, and traceback) and continues processing remaining servers without aborting subscription-level collection.
Resilience tests and changelog
tests/providers/azure/services/postgresql/postgresql_service_test.py, prowler/CHANGELOG.md
Adds MagicMock import, _make_server helper, and Test_PostgreSQL_Service_Resilience with two tests: one asserts both servers are collected when connection_throttle.enable configuration lookup fails for one (with connection_throttling=None for that server), and one asserts a hard server-details failure for one server does not prevent collection of the other. Changelog records the fix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: isolating per-server collection failures in Azure PostgreSQL to prevent one server's failure from dropping others.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering context, root cause analysis, solution details, review steps, test instructions, and completed checklist items against the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Conflict Markers Resolved

All conflict markers have been successfully resolved in this pull request.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@prowler/providers/azure/services/postgresql/postgresql_service.py`:
- Around line 165-174: The method shown in the diff now correctly returns None
as a fallback when the connection_throttle.enable parameter is not found, but
the Server model class still declares the connection_throttling attribute with a
type annotation of just str instead of str | None. Update the type annotation
for the Server.connection_throttling attribute (referenced at line 231) to str |
None to accurately reflect that this attribute can be either a string value or
None, aligning the model definition with the actual runtime behavior of the
method that populates it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ba42f094-bbb8-41b6-afd5-2adbc2f651ad

📥 Commits

Reviewing files that changed from the base of the PR and between 24e3182 and 4ead3a6.

📒 Files selected for processing (3)
  • prowler/CHANGELOG.md
  • prowler/providers/azure/services/postgresql/postgresql_service.py
  • tests/providers/azure/services/postgresql/postgresql_service_test.py

Comment thread prowler/providers/azure/services/postgresql/postgresql_service.py
Reflect the None fallback from _get_connection_throttling in the Server
model and the method return annotation (per review feedback).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
prowler/providers/azure/services/postgresql/postgresql_service.py (1)

163-176: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add parameter type hints and a Google-style docstring on _get_connection_throttling.

This changed method still violates the Prowler Python conventions: parameters are untyped and the method has no docstring.

Suggested patch
     def _get_connection_throttling(
-        self, subscription, resouce_group_name, server_name
+        self, subscription: str, resouce_group_name: str, server_name: str
     ) -> str | None:
+        """Get connection throttling setting for a flexible server.
+
+        Args:
+            subscription: Azure subscription identifier.
+            resouce_group_name: Resource group containing the server.
+            server_name: PostgreSQL flexible server name.
+
+        Returns:
+            The uppercase throttling value when available, otherwise ``None``.
+        """
         client = self.clients[subscription]
         try:
             connection_throttling = client.configurations.get(
                 resouce_group_name, server_name, "connection_throttle.enable"
             )

As per coding guidelines, "prowler/**/*.py: Type hints are required for all public functions in Python code" and "Docstrings are required for all classes and methods in Python code, following Google style documentation".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prowler/providers/azure/services/postgresql/postgresql_service.py` around
lines 163 - 176, The `_get_connection_throttling` method is missing parameter
type hints and a Google-style docstring, violating Prowler's Python conventions.
Add type hints to the three parameters (subscription, resouce_group_name,
server_name) based on their usage in the method body, and add a Google-style
docstring above the method that documents the method's purpose, describes each
parameter, specifies the return value, and explains the behavior regarding
PostgreSQL 16+ compatibility mentioned in the existing comment.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@prowler/providers/azure/services/postgresql/postgresql_service.py`:
- Around line 163-176: The `_get_connection_throttling` method is missing
parameter type hints and a Google-style docstring, violating Prowler's Python
conventions. Add type hints to the three parameters (subscription,
resouce_group_name, server_name) based on their usage in the method body, and
add a Google-style docstring above the method that documents the method's
purpose, describes each parameter, specifies the return value, and explains the
behavior regarding PostgreSQL 16+ compatibility mentioned in the existing
comment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 76c9ea1f-4003-4308-8779-4d88f4fe71cf

📥 Commits

Reviewing files that changed from the base of the PR and between 4ead3a6 and 636050a.

📒 Files selected for processing (1)
  • prowler/providers/azure/services/postgresql/postgresql_service.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

provider/azure Issues/PRs related with the Azure provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant