-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Snowflake destination: support key pair authentication #14388
Changes from 16 commits
32118e5
9297364
0aba63c
e5b5089
aae17fc
ab47744
1e5f89e
554297b
167dc28
372700a
01aecdc
9af8bd7
794035f
f93c5c5
b009d33
bc1c922
1f37c52
1db5b13
35eee8b
69a718d
1b10b97
d05387a
9963f71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
import io.airbyte.db.jdbc.DefaultJdbcDatabase; | ||
import io.airbyte.db.jdbc.JdbcDatabase; | ||
import java.io.IOException; | ||
import java.io.PrintWriter; | ||
import java.net.URI; | ||
import java.net.URLEncoder; | ||
import java.net.http.HttpClient; | ||
|
@@ -48,6 +49,9 @@ public class SnowflakeDatabase { | |
.version(HttpClient.Version.HTTP_2) | ||
.connectTimeout(Duration.ofSeconds(10)) | ||
.build(); | ||
public static final String PRIVATE_KEY_FILE_NAME = "rsa_key.p8"; | ||
public static final String PRIVATE_KEY_FIELD_NAME = "private_key"; | ||
public static final String PASSPHRASE = "passphrase"; | ||
|
||
public static HikariDataSource createDataSource(final JsonNode config) { | ||
final HikariDataSource dataSource = new HikariDataSource(); | ||
|
@@ -92,6 +96,15 @@ public static HikariDataSource createDataSource(final JsonNode config) { | |
dataSource.setUsername(username); | ||
dataSource.setPassword(credentials.get("password").asText()); | ||
|
||
} else if (credentials != null && credentials.has(PRIVATE_KEY_FIELD_NAME)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the following scenario is possible and is a bug:
Could you please test this use case and verify that it behaves as intended (Snowflake source will use private key even if password has been previously configured? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, fortunately it is not a case, because from UI we obtain config just with on option for credentials : password, oauth2 or key pair, and for example:
So here we don't have password from first sync in config, password is stored, but not passed to connector if another auth option is chosen. |
||
LOGGER.debug("Login mode with key pair is used"); | ||
dataSource.setUsername(username); | ||
final String privateKeyValue = credentials.get(PRIVATE_KEY_FIELD_NAME).asText(); | ||
createPrivateKeyFile(PRIVATE_KEY_FILE_NAME, privateKeyValue); | ||
properties.put("private_key_file", PRIVATE_KEY_FILE_NAME); | ||
if (credentials.has(PASSPHRASE)) { | ||
properties.put("private_key_file_pwd", credentials.get(PASSPHRASE).asText()); | ||
} | ||
} else { | ||
LOGGER.warn( | ||
"Obsolete User/password login mode is used. Please re-create a connection to use the latest connector's version"); | ||
|
@@ -128,6 +141,14 @@ public static HikariDataSource createDataSource(final JsonNode config) { | |
return dataSource; | ||
} | ||
|
||
private static void createPrivateKeyFile(final String fileName, final String fileValue) { | ||
try (final PrintWriter out = new PrintWriter(fileName, StandardCharsets.UTF_8)) { | ||
out.print(fileValue); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Failed to create file for private key"); | ||
} | ||
} | ||
|
||
private static String getAccessTokenUsingRefreshToken(final String hostName, | ||
final String clientId, | ||
final String clientSecret, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
public class NormalizationRunnerFactory { | ||
|
||
public static final String BASE_NORMALIZATION_IMAGE_NAME = "airbyte/normalization"; | ||
public static final String NORMALIZATION_VERSION = "0.2.6"; | ||
public static final String NORMALIZATION_VERSION = "0.2.7"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hint: do not forget to publish it additionally to connector itself |
||
|
||
static final Map<String, ImmutablePair<String, DefaultNormalizationRunner.DestinationType>> NORMALIZATION_MAPPING = | ||
ImmutableMap.<String, ImmutablePair<String, DefaultNormalizationRunner.DestinationType>>builder() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I understand it is possible for both
private_key
andpassword
fields to be configured and when that is the case, this code will always chose to use private key for auth while the code inSnowflakeDatabase
will always chose to use username/password for auth. Is this not the case?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as at destination, config object contains data just for one auth type