Skip to content
This repository was archived by the owner on May 17, 2024. It is now read-only.

Commit aa8c65a

Browse files
committed
add basic key/pair support
1 parent 992651d commit aa8c65a

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

data_diff/dbt.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,12 +480,11 @@ def set_connection(self):
480480
credentials, conn_type = self._get_connection_creds()
481481

482482
if conn_type == "snowflake":
483-
if credentials.get("password") is None or credentials.get("private_key_path") is not None:
484-
raise Exception("Only password authentication is currently supported for Snowflake.")
483+
if credentials.get("authenticator") is not None or credentials.get("private_key_passphrase") is not None:
484+
raise Exception("Federated authentication and key/pair with passphrase is not yet supported for Snowflake.")
485485
conn_info = {
486486
"driver": conn_type,
487487
"user": credentials.get("user"),
488-
"password": credentials.get("password"),
489488
"account": credentials.get("account"),
490489
"database": credentials.get("database"),
491490
"warehouse": credentials.get("warehouse"),
@@ -494,6 +493,15 @@ def set_connection(self):
494493
}
495494
self.threads = credentials.get("threads")
496495
self.requires_upper = True
496+
497+
if credentials.get("private_key_path") is not None:
498+
if credentials.get("password") is not None:
499+
raise Exception("Cannot use password and key at the same time")
500+
conn_info["key"] = credentials.get("private_key_path")
501+
elif credentials.get("password") is not None:
502+
conn_info["password"] = credentials.get("password")
503+
else:
504+
raise Exception("Password or key authentication not provided.")
497505
elif conn_type == "bigquery":
498506
method = credentials.get("method")
499507
# there are many connection types https://docs.getdbt.com/reference/warehouse-setups/bigquery-setup#oauth-via-gcloud

tests/test_dbt.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def test_get_project_dict(self, mock_open):
136136
self.assertEqual(project_dict, expected_dict)
137137
mock_open.assert_called_once_with(Path(PROJECT_FILE))
138138

139-
def test_set_connection_snowflake_success(self):
139+
def test_set_connection_snowflake_success_password(self):
140140
expected_driver = "snowflake"
141141
expected_credentials = {"user": "user", "password": "password"}
142142
mock_self = Mock()
@@ -148,9 +148,25 @@ def test_set_connection_snowflake_success(self):
148148
self.assertEqual(mock_self.connection.get("driver"), expected_driver)
149149
self.assertEqual(mock_self.connection.get("user"), expected_credentials["user"])
150150
self.assertEqual(mock_self.connection.get("password"), expected_credentials["password"])
151+
self.assertEqual(mock_self.connection.get("key"), None)
151152
self.assertEqual(mock_self.requires_upper, True)
152153

153-
def test_set_connection_snowflake_no_password(self):
154+
def test_set_connection_snowflake_success_key(self):
155+
expected_driver = "snowflake"
156+
expected_credentials = {"user": "user", "private_key_path": "private_key_path"}
157+
mock_self = Mock()
158+
mock_self._get_connection_creds.return_value = (expected_credentials, expected_driver)
159+
160+
DbtParser.set_connection(mock_self)
161+
162+
self.assertIsInstance(mock_self.connection, dict)
163+
self.assertEqual(mock_self.connection.get("driver"), expected_driver)
164+
self.assertEqual(mock_self.connection.get("user"), expected_credentials["user"])
165+
self.assertEqual(mock_self.connection.get("password"), None)
166+
self.assertEqual(mock_self.connection.get("key"), expected_credentials["private_key_path"])
167+
self.assertEqual(mock_self.requires_upper, True)
168+
169+
def test_set_connection_snowflake_no_key_or_password(self):
154170
expected_driver = "snowflake"
155171
expected_credentials = {"user": "user"}
156172
mock_self = Mock()
@@ -160,6 +176,39 @@ def test_set_connection_snowflake_no_password(self):
160176
DbtParser.set_connection(mock_self)
161177

162178
self.assertNotIsInstance(mock_self.connection, dict)
179+
180+
def test_set_connection_snowflake_authenticator(self):
181+
expected_driver = "snowflake"
182+
expected_credentials = {"user": "user", "authenticator": "authenticator"}
183+
mock_self = Mock()
184+
mock_self._get_connection_creds.return_value = (expected_credentials, expected_driver)
185+
186+
with self.assertRaises(Exception):
187+
DbtParser.set_connection(mock_self)
188+
189+
self.assertNotIsInstance(mock_self.connection, dict)
190+
191+
def test_set_connection_snowflake_key_and_password(self):
192+
expected_driver = "snowflake"
193+
expected_credentials = {"user": "user", "private_key_path": "private_key_path", "password": "password"}
194+
mock_self = Mock()
195+
mock_self._get_connection_creds.return_value = (expected_credentials, expected_driver)
196+
197+
with self.assertRaises(Exception):
198+
DbtParser.set_connection(mock_self)
199+
200+
self.assertNotIsInstance(mock_self.connection, dict)
201+
202+
def test_set_connection_snowflake_private_key_passphrase(self):
203+
expected_driver = "snowflake"
204+
expected_credentials = {"user": "user", "private_key_passphrase": "private_key_passphrase"}
205+
mock_self = Mock()
206+
mock_self._get_connection_creds.return_value = (expected_credentials, expected_driver)
207+
208+
with self.assertRaises(Exception):
209+
DbtParser.set_connection(mock_self)
210+
211+
self.assertNotIsInstance(mock_self.connection, dict)
163212

164213
def test_set_connection_bigquery_success(self):
165214
expected_driver = "bigquery"

0 commit comments

Comments
 (0)