Skip to content

handle ssl cert in dbt cli config#1323

Merged
Ishankoradia merged 4 commits intomainfrom
ssl-cert-in-dbt-runs
May 4, 2026
Merged

handle ssl cert in dbt cli config#1323
Ishankoradia merged 4 commits intomainfrom
ssl-cert-in-dbt-runs

Conversation

@Ishankoradia
Copy link
Copy Markdown
Contributor

@Ishankoradia Ishankoradia commented Apr 30, 2026

Summary by CodeRabbit

  • Bug Fixes

    • SSL handling: map provided SSL "mode" to the DBT profile's sslmode.
    • SSL CA certificates are kept as in-memory content and no longer written to disk.
    • Validation added: a project directory is required when supplying a CA certificate.
  • Tests

    • Added tests covering sslmode-only behavior, CA certificate handling without disk writes, and missing project-directory error.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Walkthrough

DBT SSL mapping now sets sslmode from ssl_mode.mode. If ssl_mode.ca_certificate is provided the mapper requires dbt_project_params.org_project_dir, places the certificate into conn_info["sslrootcert_content"], and sets conn_info["sslrootcert"] to the canonical sslrootcert.pem path without writing the file to disk.

Changes

SSL Certificate Content Injection

Layer / File(s) Summary
Data Shape / Types
ddpui/ddpdbt/schema.py
Adds Optional import from typing (type import only).
Data Mapping
ddpui/core/dbtfunctions.py
Sets conn_info["sslmode"] from ssl_mode["mode"] when present. When ssl_mode["ca_certificate"] exists requires dbt_project_params.org_project_dir (raises if missing), sets conn_info["sslrootcert_content"] to the certificate string, and sets conn_info["sslrootcert"] to os.path.join(org_project_dir, "sslrootcert.pem") without writing the file.
Tests / Validation
ddpui/tests/core/test_dbtfunctions.py
Imports os. Updates SSL test to assert sslmode, sslrootcert, and sslrootcert_content are present and that sslrootcert.pem is NOT created on disk. Adds test for ssl_mode with mode only (no cert) and test that missing org_project_dir raises an error containing "org_project_dir is required".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: handling SSL certificates in DBT CLI configuration by mapping SSL parameters and managing CA certificates in the DBT profile.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ssl-cert-in-dbt-runs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

Copy link
Copy Markdown
Contributor

@siddhant3030 siddhant3030 left a comment

Choose a reason for hiding this comment

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

ddpui/core/dbtfunctions.py:48sslrootcert_content isn't consumed anywhere in DDP_backend. Is there a paired prefect-proxy PR that reads this key and writes the cert to disk before dbt runs? Without it, sslrootcert will point to a file that doesn't exist.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
ddpui/tests/core/test_dbtfunctions.py (1)

126-130: ⚡ Quick win

assert False is stripped by -O and the bare Exception catch hides unrelated errors (Ruff B011 / BLE001)

Use pytest.raises for both correctness and clarity:

♻️ Proposed refactor
-    try:
-        map_airbyte_destination_spec_to_dbtcli_profile(conn_info, dbt_project_params)
-        assert False, "should have raised"
-    except Exception as e:
-        assert "org_project_dir is required" in str(e)
+    import pytest
+    with pytest.raises(Exception, match="org_project_dir is required"):
+        map_airbyte_destination_spec_to_dbtcli_profile(conn_info, dbt_project_params)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/tests/core/test_dbtfunctions.py` around lines 126 - 130, The test
currently uses a try/except with assert False and a bare Exception which is
fragile and suppressed by -O; replace it with pytest.raises to explicitly assert
the expected error type and message from
map_airbyte_destination_spec_to_dbtcli_profile: wrap the call in
pytest.raises(ExpectedException, match="org_project_dir is required") (choose
the actual exception type raised by the function, e.g., ValueError) so the test
fails for unexpected exceptions and correctly verifies the error text.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ddpui/core/dbtfunctions.py`:
- Around line 44-48: The code accesses dbt_project_params.org_project_dir
without ensuring dbt_project_params is not None; update the conditional that
checks ca_certificate to first verify dbt_project_params is truthy and then
org_project_dir (e.g., change the check to something like "if not
dbt_project_params or not dbt_project_params.org_project_dir") so that when
dbt_project_params is None you raise the same "org_project_dir is required..."
Exception instead of triggering an AttributeError; reference the ca_certificate
variable and dbt_project_params.org_project_dir in your fix.
- Around line 50-53: conn_info sets sslrootcert_content but no code writes it to
disk, so dbt's sslrootcert path will point to a missing file when sslmode:
verify-ca; fix by writing conn_info["sslrootcert_content"] to the file path in
conn_info["sslrootcert"] (under dbt_project_params.org_project_dir, named
sslrootcert.pem) before the profile is saved or before the dbt CLI subprocess is
invoked. Ensure this write happens prior to calling
update_dbt_cli_profile_block(credentials=dbt_creds) and prior to any code that
renders/dumps profiles.yml so the actual certificate file exists on disk when
dbt runs. Also ensure file permissions are appropriate and handle/raise errors
if the certificate content is missing.

---

Nitpick comments:
In `@ddpui/tests/core/test_dbtfunctions.py`:
- Around line 126-130: The test currently uses a try/except with assert False
and a bare Exception which is fragile and suppressed by -O; replace it with
pytest.raises to explicitly assert the expected error type and message from
map_airbyte_destination_spec_to_dbtcli_profile: wrap the call in
pytest.raises(ExpectedException, match="org_project_dir is required") (choose
the actual exception type raised by the function, e.g., ValueError) so the test
fails for unexpected exceptions and correctly verifies the error text.
🪄 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: CHILL

Plan: Pro

Run ID: 60bd1523-d151-4171-ab8a-a768fbc298a3

📥 Commits

Reviewing files that changed from the base of the PR and between 94269f6 and 6e83ef7.

📒 Files selected for processing (2)
  • ddpui/core/dbtfunctions.py
  • ddpui/tests/core/test_dbtfunctions.py

Comment thread ddpui/core/dbtfunctions.py
Comment thread ddpui/core/dbtfunctions.py
@sentry
Copy link
Copy Markdown

sentry Bot commented May 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.42%. Comparing base (94269f6) to head (003d6cb).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1323   +/-   ##
=======================================
  Coverage   58.42%   58.42%           
=======================================
  Files         132      132           
  Lines       15653    15653           
=======================================
  Hits         9146     9146           
  Misses       6507     6507           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
ddpui/core/dbtfunctions.py (1)

50-53: ⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

sslrootcert.pem still never written to disk — verify-ca dbt runs will fail.

sslrootcert_content is stored in conn_info and sslrootcert points to a path that doesn't exist. The test intentionally asserts the file is absent at setup time ("runtime cert writing"), but no code in this PR (or anywhere else in the codebase per the previous exhaustive verification) reads sslrootcert_content and materializes the file before the dbt CLI subprocess runs. Every verify-ca connection will fail with a missing-file error until that write step exists.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/core/dbtfunctions.py` around lines 50 - 53, conn_info currently stores
sslrootcert_content and points sslrootcert to a path that doesn't exist; before
launching the dbt CLI you must materialize that PEM file. In the function that
builds/returns conn_info or immediately before calling the subprocess that runs
dbt (locate where conn_info is used to invoke dbt), write
conn_info["sslrootcert_content"] to
os.path.join(dbt_project_params.org_project_dir, "sslrootcert.pem"), set safe
file permissions (e.g., 0600), perform an atomic write (tmp file + rename) and
ensure conn_info["sslrootcert"] points to that created file so verify-ca
connections can find it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ddpui/tests/core/test_dbtfunctions.py`:
- Around line 111-118: Replace the try/except + assert False pattern in
test_map_airbyte_destination_spec_to_dbtcli_profile_ssl_no_org_project_dir with
pytest.raises to avoid B011 and BLE001: wrap the call to
map_airbyte_destination_spec_to_dbtcli_profile(conn_info, None) in a with
pytest.raises(<expected-exception-type>, match="org_project_dir is required")
block (use the concrete exception that the function raises, e.g., ValueError) so
the test asserts the specific exception and message instead of catching all
exceptions or relying on assert False.

---

Duplicate comments:
In `@ddpui/core/dbtfunctions.py`:
- Around line 50-53: conn_info currently stores sslrootcert_content and points
sslrootcert to a path that doesn't exist; before launching the dbt CLI you must
materialize that PEM file. In the function that builds/returns conn_info or
immediately before calling the subprocess that runs dbt (locate where conn_info
is used to invoke dbt), write conn_info["sslrootcert_content"] to
os.path.join(dbt_project_params.org_project_dir, "sslrootcert.pem"), set safe
file permissions (e.g., 0600), perform an atomic write (tmp file + rename) and
ensure conn_info["sslrootcert"] points to that created file so verify-ca
connections can find 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: CHILL

Plan: Pro

Run ID: 8b57403f-9ff9-4f72-ac1a-9591d0a7e26f

📥 Commits

Reviewing files that changed from the base of the PR and between 6e83ef7 and 003d6cb.

📒 Files selected for processing (3)
  • ddpui/core/dbtfunctions.py
  • ddpui/ddpdbt/schema.py
  • ddpui/tests/core/test_dbtfunctions.py
✅ Files skipped from review due to trivial changes (1)
  • ddpui/ddpdbt/schema.py

Comment on lines +111 to +118
def test_map_airbyte_destination_spec_to_dbtcli_profile_ssl_no_org_project_dir():
"""Tests ssl with ca_certificate but no dbt_project_params raises"""
conn_info = {"ssl_mode": {"mode": "verify-ca", "ca_certificate": "ca_certificate"}}
try:
map_airbyte_destination_spec_to_dbtcli_profile(conn_info, None)
assert False, "should have raised"
except Exception as e:
assert "org_project_dir is required" in str(e)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace try/except + assert False with pytest.raises.

Two Ruff-flagged problems here:

  1. B011assert False is silently removed under python -O, so the "should have raised" sentinel never fires in optimised mode.
  2. BLE001 — bare except Exception swallows any unexpected error (AttributeError, KeyError, etc.) and checks its message against "org_project_dir is required", meaning an unrelated crash causes a false-pass.

pytest.raises fixes both in one move:

🛠️ Proposed fix
+import pytest
+
 def test_map_airbyte_destination_spec_to_dbtcli_profile_ssl_no_org_project_dir():
     """Tests ssl with ca_certificate but no dbt_project_params raises"""
     conn_info = {"ssl_mode": {"mode": "verify-ca", "ca_certificate": "ca_certificate"}}
-    try:
-        map_airbyte_destination_spec_to_dbtcli_profile(conn_info, None)
-        assert False, "should have raised"
-    except Exception as e:
-        assert "org_project_dir is required" in str(e)
+    with pytest.raises(Exception, match="org_project_dir is required"):
+        map_airbyte_destination_spec_to_dbtcli_profile(conn_info, None)
🧰 Tools
🪛 Ruff (0.15.12)

[warning] 116-116: Do not assert False (python -O removes these calls), raise AssertionError()

Replace assert False

(B011)


[warning] 117-117: Do not catch blind exception: Exception

(BLE001)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ddpui/tests/core/test_dbtfunctions.py` around lines 111 - 118, Replace the
try/except + assert False pattern in
test_map_airbyte_destination_spec_to_dbtcli_profile_ssl_no_org_project_dir with
pytest.raises to avoid B011 and BLE001: wrap the call to
map_airbyte_destination_spec_to_dbtcli_profile(conn_info, None) in a with
pytest.raises(<expected-exception-type>, match="org_project_dir is required")
block (use the concrete exception that the function raises, e.g., ValueError) so
the test asserts the specific exception and message instead of catching all
exceptions or relying on assert False.

@Ishankoradia Ishankoradia merged commit 9594f2a into main May 4, 2026
5 checks passed
@Ishankoradia Ishankoradia deleted the ssl-cert-in-dbt-runs branch May 4, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants