Skip to content

Commit e6e931d

Browse files
committed
SNOW-2306184: config refactor - snowsql env support
1 parent 37a19b4 commit e6e931d

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

src/snowflake/cli/api/config.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,18 @@ class ConnectionConfig:
100100
authenticator: Optional[str] = None
101101
workload_identity_provider: Optional[str] = None
102102
private_key_file: Optional[str] = None
103+
private_key_passphrase: Optional[str] = field(default=None, repr=False)
104+
token: Optional[str] = field(default=None, repr=False)
105+
session_token: Optional[str] = field(default=None, repr=False)
106+
master_token: Optional[str] = field(default=None, repr=False)
103107
token_file_path: Optional[str] = None
104108
oauth_client_id: Optional[str] = None
105109
oauth_client_secret: Optional[str] = None
106110
oauth_authorization_url: Optional[str] = None
107111
oauth_token_request_url: Optional[str] = None
108112
oauth_redirect_uri: Optional[str] = None
109113
oauth_scope: Optional[str] = None
110-
oatuh_enable_pkce: Optional[bool] = None
114+
oauth_enable_pkce: Optional[bool] = None
111115
oauth_enable_refresh_tokens: Optional[bool] = None
112116
oauth_enable_single_use_refresh_tokens: Optional[bool] = None
113117
client_store_temporary_credential: Optional[bool] = None

src/snowflake/cli/api/config_ng/sources.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,14 +388,18 @@ class CliEnvironment(ValueSource):
388388
"private_key_file",
389389
"private_key_path", # Used by integration tests
390390
"private_key_raw", # Used by integration tests
391+
"private_key_passphrase", # Private key passphrase for encrypted keys
392+
"token", # OAuth token
393+
"session_token", # Session token for session-based authentication
394+
"master_token", # Master token for advanced authentication
391395
"token_file_path",
392396
"oauth_client_id",
393397
"oauth_client_secret",
394398
"oauth_authorization_url",
395399
"oauth_token_request_url",
396400
"oauth_redirect_uri",
397401
"oauth_scope",
398-
"oatuh_enable_pkce",
402+
"oauth_enable_pkce", # Fixed typo: was "oatuh_enable_pkce"
399403
"oauth_enable_refresh_tokens",
400404
"oauth_enable_single_use_refresh_tokens",
401405
"client_store_temporary_credential",

src/snowflake/cli/api/config_provider.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,53 @@ def get_all_connections(self) -> dict:
7070
"""Get all connection configurations."""
7171
...
7272

73+
def _transform_private_key_raw(self, connection_dict: dict) -> dict:
74+
"""
75+
Transform private_key_raw to private_key_file for ConnectionContext compatibility.
76+
77+
The ConnectionContext dataclass doesn't have a private_key_raw field, so it gets
78+
filtered out by merge_with_config. To work around this, we write private_key_raw
79+
content to a temporary file and return it as private_key_file.
80+
81+
Args:
82+
connection_dict: Connection configuration dictionary
83+
84+
Returns:
85+
Modified connection dictionary with private_key_raw transformed to private_key_file
86+
"""
87+
if "private_key_raw" not in connection_dict:
88+
return connection_dict
89+
90+
# Don't transform if private_key_file is already set
91+
if "private_key_file" in connection_dict:
92+
return connection_dict
93+
94+
import os
95+
import tempfile
96+
97+
try:
98+
# Create a temporary file with the private key content
99+
with tempfile.NamedTemporaryFile(
100+
mode="w", suffix=".pem", delete=False
101+
) as f:
102+
f.write(connection_dict["private_key_raw"])
103+
temp_file_path = f.name
104+
105+
# Set restrictive permissions on the temporary file
106+
os.chmod(temp_file_path, 0o600)
107+
108+
# Create a copy of the connection dict with the transformation
109+
result = connection_dict.copy()
110+
result["private_key_file"] = temp_file_path
111+
del result["private_key_raw"]
112+
113+
return result
114+
115+
except Exception:
116+
# If transformation fails, return original dict
117+
# The error will be handled downstream
118+
return connection_dict
119+
73120

74121
class LegacyConfigProvider(ConfigProvider):
75122
"""
@@ -113,7 +160,8 @@ def read_config(self) -> None:
113160
def get_connection_dict(self, connection_name: str) -> dict:
114161
from snowflake.cli.api.config import get_connection_dict
115162

116-
return get_connection_dict(connection_name)
163+
result = get_connection_dict(connection_name)
164+
return self._transform_private_key_raw(result)
117165

118166
def get_all_connections(self) -> dict:
119167
from snowflake.cli.api.config import get_all_connections
@@ -377,7 +425,8 @@ def get_connection_dict(self, connection_name: str) -> dict:
377425
Returns:
378426
Dictionary of connection parameters
379427
"""
380-
return self._get_connection_dict_internal(connection_name)
428+
result = self._get_connection_dict_internal(connection_name)
429+
return self._transform_private_key_raw(result)
381430

382431
def _get_all_connections_dict(self) -> Dict[str, Dict[str, Any]]:
383432
"""

src/snowflake/cli/api/connections.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class ConnectionContext:
4747
authenticator: Optional[str] = None
4848
workload_identity_provider: Optional[str] = None
4949
private_key_file: Optional[str] = None
50+
private_key_passphrase: Optional[str] = field(default=None, repr=False)
5051
warehouse: Optional[str] = None
5152
mfa_passcode: Optional[str] = None
5253
token: Optional[str] = None

0 commit comments

Comments
 (0)