Skip to content
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

check for permissions error on snowflake destinations #21764

Merged
merged 7 commits into from
Jan 25, 2023

Conversation

jbfbell
Copy link
Contributor

@jbfbell jbfbell commented Jan 24, 2023

What

Check for known Configuration Issues with the Snowflake Destination for #20343

How

Verify the exceptions thrown do not match any of our expected exception scenarios.

🚨 User Impact 🚨

For users who walk through the Snowflake Destination setup and select "Mirror Source" ( or any user who doesn't have the permissions properly configured) they will see a configuration error in the UI.

Pre-merge Checklist

Expand the relevant checklist and delete the others.

New Connector

Community member or Airbyter

  • Community member? Grant edit access to maintainers (instructions)
  • Secrets in the connector's spec are annotated with airbyte_secret
  • Unit & integration tests added and passing. Community members, please provide proof of success locally e.g: screenshot or copy-paste unit, integration, and acceptance test output. To run acceptance tests for a Python connector, follow instructions in the README. For java connectors run ./gradlew :airbyte-integrations:connectors:<name>:integrationTest.
  • Code reviews completed
  • Documentation updated
    • Connector's README.md
    • Connector's bootstrap.md. See description and examples
    • docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
    • docs/integrations/README.md
    • airbyte-integrations/builds.md
  • PR name follows PR naming conventions

Airbyter

If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.

  • Create a non-forked branch based on this PR and test the below items on it
  • Build is successful
  • If new credentials are required for use in CI, add them to GSM. Instructions.
  • /test connector=connectors/<name> command is passing
  • New Connector version released on Dockerhub by running the /publish command described here
  • After the connector is published, connector added to connector index as described here
  • Seed specs have been re-generated by building the platform and committing the changes to the seed spec files, as described here
Updating a connector

Community member or Airbyter

  • Grant edit access to maintainers (instructions)
  • Secrets in the connector's spec are annotated with airbyte_secret
  • Unit & integration tests added and passing. Community members, please provide proof of success locally e.g: screenshot or copy-paste unit, integration, and acceptance test output. To run acceptance tests for a Python connector, follow instructions in the README. For java connectors run ./gradlew :airbyte-integrations:connectors:<name>:integrationTest.
  • Code reviews completed
  • Documentation updated
    • Connector's README.md
    • Connector's bootstrap.md. See description and examples
    • Changelog updated in docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
  • PR name follows PR naming conventions

Airbyter

If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.

  • Create a non-forked branch based on this PR and test the below items on it
  • Build is successful
  • If new credentials are required for use in CI, add them to GSM. Instructions.
  • /test connector=connectors/<name> command is passing
  • New Connector version released on Dockerhub and connector version bumped by running the /publish command described here
Connector Generator
  • Issue acceptance criteria met
  • PR name follows PR naming conventions
  • If adding a new generator, add it to the list of scaffold modules being tested
  • The generator test modules (all connectors with -scaffold in their name) have been updated with the latest scaffold by running ./gradlew :airbyte-integrations:connector-templates:generator:testScaffoldTemplates then checking in your changes
  • Documentation which references the generator is updated as needed

Tests

Unit

Put your unit tests output here.

Integration

Put your integration tests output here.

Acceptance

Put your acceptance tests output here.

@jbfbell jbfbell requested a review from a team as a code owner January 24, 2023 01:18
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 01:20 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 01:20 — with GitHub Actions Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Jan 24, 2023

Affected Connector Report

NOTE ⚠️ Changes in this PR affect the following connectors. Make sure to do the following as needed:

  • Run integration tests
  • Bump connector or module version
  • Add changelog
  • Publish the new version

✅ Sources (0)

Connector Version Changelog Publish
  • See "Actionable Items" below for how to resolve warnings and errors.

❌ Destinations (21)

Connector Version Changelog Publish
destination-azure-blob-storage 0.1.6
destination-clickhouse 0.2.2
(changelog missing)
destination-clickhouse-strict-encrypt 0.2.2 🔵
(ignored)
🔵
(ignored)
destination-databricks 0.3.1
destination-dynamodb 0.1.7
destination-gcs 0.2.14
destination-mariadb-columnstore 0.1.7
destination-mssql 0.1.22
destination-mssql-strict-encrypt 0.1.22 🔵
(ignored)
🔵
(ignored)
destination-mysql 0.1.20
destination-mysql-strict-encrypt 0.1.21
(mismatch: 0.1.20)
🔵
(ignored)
🔵
(ignored)
destination-oracle 0.1.19
destination-oracle-strict-encrypt 0.1.19 🔵
(ignored)
🔵
(ignored)
destination-postgres 0.3.26
destination-postgres-strict-encrypt 0.3.26 🔵
(ignored)
🔵
(ignored)
destination-redshift 0.3.54
destination-rockset 0.1.4
destination-snowflake 0.4.45
destination-teradata 0.1.0
destination-tidb 0.1.0
destination-yugabytedb 0.1.0
  • See "Actionable Items" below for how to resolve warnings and errors.

👀 Other Modules (1)

  • base-normalization

Actionable Items

(click to expand)

Category Status Actionable Item
Version
mismatch
The version of the connector is different from its normal variant. Please bump the version of the connector.

doc not found
The connector does not seem to have a documentation file. This can be normal (e.g. basic connector like source-jdbc is not published or documented). Please double-check to make sure that it is not a bug.
Changelog
doc not found
The connector does not seem to have a documentation file. This can be normal (e.g. basic connector like source-jdbc is not published or documented). Please double-check to make sure that it is not a bug.

changelog missing
There is no chnagelog for the current version of the connector. If you are the author of the current version, please add a changelog.
Publish
not in seed
The connector is not in the seed file (e.g. source_definitions.yaml), so its publication status cannot be checked. This can be normal (e.g. some connectors are cloud-specific, and only listed in the cloud seed file). Please double-check to make sure that it is not a bug.

diff seed version
The connector exists in the seed file, but the latest version is not listed there. This usually means that the latest version is not published. Please use the /publish command to publish the latest version.

@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

/test connector=destination-snowflake

🕑 destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/3992130839
❌ destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/3992130839
🐛 https://gradle.com/s/5qgje3fz7faui

Build Failed

Test summary info:

Could not find result summary

@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

/test connector=connectors/destination-snowflake

🕑 connectors/destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/3992132889
❌ connectors/destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/3992132889
🐛 https://gradle.com/s/e324xn7azns5k

Build Failed

Test summary info:

Could not find result summary

@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

/test connector=connectors/destination-jdbc

🕑 connectors/destination-jdbc https://github.com/airbytehq/airbyte/actions/runs/3992154667
✅ connectors/destination-jdbc https://github.com/airbytehq/airbyte/actions/runs/3992154667
Python tests coverage:

Name                                                              Stmts   Miss  Cover
-------------------------------------------------------------------------------------
normalization/transform_config/__init__.py                            2      0   100%
normalization/transform_catalog/reserved_keywords.py                 14      0   100%
normalization/transform_catalog/__init__.py                           2      0   100%
normalization/destination_type.py                                    14      0   100%
normalization/__init__.py                                             4      0   100%
normalization/transform_catalog/destination_name_transformer.py     166      8    95%
normalization/transform_catalog/table_name_registry.py              174     34    80%
normalization/transform_config/transform.py                         189     48    75%
normalization/transform_catalog/utils.py                             51     14    73%
normalization/transform_catalog/dbt_macro.py                         22      7    68%
normalization/transform_catalog/catalog_processor.py                147     80    46%
normalization/transform_catalog/transform.py                         61     38    38%
normalization/transform_catalog/stream_processor.py                 595    400    33%
-------------------------------------------------------------------------------------
TOTAL                                                              1441    629    56%

Build Passed

Test summary info:

All Passed

@github-actions
Copy link
Contributor

github-actions bot commented Jan 24, 2023

Airbyte Code Coverage

There is no coverage information present for the Files changed

Total Project Coverage 23.97%

Copy link
Contributor

@edgao edgao left a comment

Choose a reason for hiding this comment

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

lgtm! a couple minor comments, but only the assertThrows one is really blocking

* @param e the exception to check.
* @return A ConfigErrorException with a message with actionable feedback to the user.
*/
protected Optional<ConfigErrorException> checkForKnownConfigExceptions(Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I like this! and 👍 for good javadoc

final var schemaName = "foo";
try {
Mockito.doThrow(new SQLException("TEST")).when(db).execute(Mockito.anyString());
createSchemaIfNotExists(db, schemaName);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there's an assertThrows method for this exact situation - currently your test will pass even if this method doesn't throw

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh good catch! that's what I was trying to remember

@Override
protected Optional<ConfigErrorException> checkForKnownConfigExceptions(Exception e) {
if (e instanceof SnowflakeSQLException && e.getMessage().contains(NO_PRIVILEGES_ERROR_MESSAGE)) {
return Optional.of(new ConfigErrorException("Encountered Error with Snowflake Configuration, please verify your privileges", e));
Copy link
Contributor

Choose a reason for hiding this comment

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

can we be more specific about what permissions are needed? (this is an actual question, I don't know how specific snowflake's error message is)

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to Ed's comment, do we know what are the ways a customer can resolve this

Schema 'PUBLIC' already exists, but current role has no privileges on it. If this is unexpected and you cannot resolve this problem, contact your system administrator.

Also, looking at the SnowflakeSQLException class, it extends off of SQLException which has a method getSQLState(), is that something we can more accurately map so this test doesn't become fragile?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The SQL state was SQLState = "42710" but AFAICT this didn't map to anything beside the SQLComilationError here's the entire content of the exception

this = {SnowflakeInternalStagingSqlOperations@5796} 
e = {SnowflakeSQLException@5797} "net.snowflake.client.jdbc.SnowflakeSQLException: SQL compilation error:\nSchema 'PUBLIC' already exists, but current role has no privileges on it. If this is unexpected and you cannot resolve this problem, contact your system administrator. ACCOUNTADMIN role may be required to manage the privileges on the object."
  queryId = "01a9da10-0000-eef5-0000-53b903d214ba"
  retryCount = 0
  issocketTimeoutNoBackoff = false
  elapsedSeconds = 0
  SQLState = "42710"
  vendorCode = 3041
  next = null
  backtrace = {Object[6]@5801} 
  detailMessage = "SQL compilation error:\nSchema 'PUBLIC' already exists, but current role has no privileges on it. If this is unexpected and you cannot resolve this problem, contact your system administrator. ACCOUNTADMIN role may be required to manage the privileges on the object."
  cause = {SnowflakeSQLException@5797} "net.snowflake.client.jdbc.SnowflakeSQLException: SQL compilation error:\nSchema 'PUBLIC' already exists, but current role has no privileges on it. If this is unexpected and you cannot resolve this problem, contact your system administrator. ACCOUNTADMIN role may be required to manage the privileges on the object."
  stackTrace = {StackTraceElement[29]@5806} 
  depth = 29
  suppressedExceptions = {Collections$EmptyList@5804}  size = 0

I'm open to any thoughts here

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a little tricky since Snowflake has poor documentation on their SQLSTATE codes but it appears a few other DB documentation Postgres and IBM both use 42710 for marking duplicate object

I'll leave it up to your discretion, although I might consider if you go with a string check to have it

ACCOUNTADMIN role may be required to manage the privileges on the object.

Since if someone were to see that within the code it makes a bit more sense what they may need to do in order to resolve their issue. Granted the usage of the ConfigErrorException is for a actionable message for the user to resolve this configuration issue

database.execute(String.format("CREATE SCHEMA IF NOT EXISTS %s;", schemaName));
schemaSet.add(schemaName);
}
} catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should log the original exception here, since it's hard to guarantee that subclasses always handle it correctly? I'm always a bit conflicted about this, since we might end up logging the same exception multiple times

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the use case hasn't presented itself I'm going to err on the side of inaction and not assume anything just yet. As for now the current behavior will log the original exception and the snowflake subclass will pass along the original exception in the Config Exception

Copy link
Contributor

@ryankfu ryankfu left a comment

Choose a reason for hiding this comment

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

LGTM, pending update of tests to use and potentially any ways you can consider for a less fragile test for SnowflakeSqlOperations

assertThrows(Exception.class, () -> executable)

@ryankfu
Copy link
Contributor

ryankfu commented Jan 24, 2023

@jbfbell base on this comment, it sounds like you followed all the steps that Airbyte documents for getting a user setup with a sync between Postgres <> Snowflake. Since it sounds like this change will only convert the Exception to a ConfigErrorException

Were you able to find the steps to mitigate this issue and if so that seems we should update our snowflake.md docs, right? From the vantage point of the user, all they know is something fails but this change doesn't alleviate the issue

@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

@jbfbell base on this comment, it sounds like you followed all the steps that Airbyte documents for getting a user setup with a sync between Postgres <> Snowflake. Since it sounds like this change will only convert the Exception to a ConfigErrorException

Were you able to find the steps to mitigate this issue and if so that seems we should update our snowflake.md docs, right? From the vantage point of the user, all they know is something fails but this change doesn't alleviate the issue

@ryankfu I think its only an issue if the user chooses to "mirror source schema" Maybe this is something to address as a part of #20561 ?

@ryankfu
Copy link
Contributor

ryankfu commented Jan 24, 2023

@jbfbell If I'm reading that ticket correctly, it's the true fix to the issue, however, if we're marking an Exception as a ConfigErrorException this won't get propagated up to our error monitoring tool. The concern is if you were able to follow our instructions and we're no longer going to report this failure then we should at least inform the user what the most probable cause is so they have a way to avoid this failure until the mirror source schema issue is resolved

@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 18:51 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 18:52 — with GitHub Actions Inactive
@octavia-squidington-iv octavia-squidington-iv added the area/documentation Improvements or additions to documentation label Jan 24, 2023
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 21:25 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 21:25 — with GitHub Actions Inactive
@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

@ryankfu Added some troubleshooting docs

@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

/publish connector=connectors/destination-snowflake

🕑 Publishing the following connectors:
connectors/destination-snowflake
https://github.com/airbytehq/airbyte/actions/runs/4000589201


Connector Did it publish? Were definitions generated?
connectors/destination-snowflake

if you have connectors that successfully published but failed definition generation, follow step 4 here ▶️

If you receive an error stating `Current role does not have permissions on the target schema` make sure that the
Snowflake destination `SCHEMA` is one that the role you've provided has permissions on. When creating a connection,
it may allow you to select `Mirror source structure` for the `Destination namespace`, which if you have followed
some of our default examples and tutorials may result in the connection trying to right to a `PUBLIC` schema.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be write instead of right

Copy link
Contributor Author

Choose a reason for hiding this comment

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

:doh: good catch

@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 24, 2023

/test connector=connectors/destination-snowflake

🕑 connectors/destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/4001414250
❌ connectors/destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/4001414250
🐛 https://gradle.com/s/z52j6wkrczsmk

Build Failed

Test summary info:

Could not find result summary

@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 23:41 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 23:41 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 23:48 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 24, 2023 23:48 — with GitHub Actions Inactive
@etsybaev
Copy link
Contributor

etsybaev commented Jan 25, 2023

/test connector=connectors/destination-snowflake

🕑 connectors/destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/4009042681
✅ connectors/destination-snowflake https://github.com/airbytehq/airbyte/actions/runs/4009042681
Python tests coverage:

Name                                                              Stmts   Miss  Cover
-------------------------------------------------------------------------------------
normalization/transform_config/__init__.py                            2      0   100%
normalization/transform_catalog/reserved_keywords.py                 14      0   100%
normalization/transform_catalog/__init__.py                           2      0   100%
normalization/destination_type.py                                    14      0   100%
normalization/__init__.py                                             4      0   100%
normalization/transform_catalog/destination_name_transformer.py     166      8    95%
normalization/transform_catalog/table_name_registry.py              174     34    80%
normalization/transform_config/transform.py                         189     48    75%
normalization/transform_catalog/utils.py                             51     14    73%
normalization/transform_catalog/dbt_macro.py                         22      7    68%
normalization/transform_catalog/catalog_processor.py                147     80    46%
normalization/transform_catalog/transform.py                         61     38    38%
normalization/transform_catalog/stream_processor.py                 595    400    33%
-------------------------------------------------------------------------------------
TOTAL                                                              1441    629    56%

Build Passed

Test summary info:

All Passed

@jbfbell jbfbell enabled auto-merge (squash) January 25, 2023 21:33
@jbfbell jbfbell disabled auto-merge January 25, 2023 21:33
@jbfbell
Copy link
Contributor Author

jbfbell commented Jan 25, 2023

/publish connector=connectors/destination-snowflake

🕑 Publishing the following connectors:
connectors/destination-snowflake
https://github.com/airbytehq/airbyte/actions/runs/4010149460


Connector Did it publish? Were definitions generated?
connectors/destination-snowflake

if you have connectors that successfully published but failed definition generation, follow step 4 here ▶️

@jbfbell jbfbell temporarily deployed to more-secrets January 25, 2023 21:35 — with GitHub Actions Inactive
@jbfbell jbfbell temporarily deployed to more-secrets January 25, 2023 21:35 — with GitHub Actions Inactive
@octavia-squidington-iii octavia-squidington-iii temporarily deployed to more-secrets January 25, 2023 23:06 — with GitHub Actions Inactive
@octavia-squidington-iii octavia-squidington-iii temporarily deployed to more-secrets January 25, 2023 23:06 — with GitHub Actions Inactive
@jbfbell jbfbell enabled auto-merge (squash) January 25, 2023 23:26
@jbfbell jbfbell merged commit 3d92cb6 into master Jan 25, 2023
@jbfbell jbfbell deleted the joseph.bell/20343/snowflake-config-issue branch January 25, 2023 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Snowflake destination: Report access to schema errors as config errors
6 participants