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

fix(imports): Error when importing charts / dashboards with missing DB credentials #30503

Merged
merged 4 commits into from
Oct 4, 2024

Conversation

fisjac
Copy link
Contributor

@fisjac fisjac commented Oct 3, 2024

SUMMARY

When importing charts, dashboards, and databases, certain databases (BigQuery) require credentials to be entered into the encrypted extra field for authorization. When importing this type of database, or any chart or dashboard that relies on this type of database, the db creation will fail generating an import failed error.

This fix implements a try except block to catch connection errors when attempting to populate db catalogs when importing a db. It prevents bigquery exceptions from being remapped to generic Exception types.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before:
https://www.loom.com/share/ca5efd11ba004c19aea9c83484bdab47?sid=6be35dfc-42e1-45b2-81dd-0a8df1d41dd6

After:
https://www.loom.com/share/a9cc247ddb434ee198f81503514f6776?sid=93c7481f-9ace-4def-9862-6567ecf2f32b

TESTING INSTRUCTIONS

Export a bigquery database or a chart/dashboard linked to a bigquery db.
Delete the underlying db
Attempt to import the db, chart, or dashboard.
The import should be successful, even though the db does not have auth creds

ADDITIONAL INFORMATION

  • Has associated issue: Dashboard Import error #30383
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

Copy link

codecov bot commented Oct 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.92%. Comparing base (76d897e) to head (b1dc06a).
Report is 835 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master   #30503       +/-   ##
===========================================
+ Coverage   60.48%   83.92%   +23.43%     
===========================================
  Files        1931      533     -1398     
  Lines       76236    38538    -37698     
  Branches     8568        0     -8568     
===========================================
- Hits        46114    32344    -13770     
+ Misses      28017     6194    -21823     
+ Partials     2105        0     -2105     
Flag Coverage Δ
hive 49.00% <33.33%> (-0.17%) ⬇️
javascript ?
mysql 76.76% <66.66%> (?)
postgres 76.89% <66.66%> (?)
presto 53.49% <33.33%> (-0.32%) ⬇️
python 83.92% <100.00%> (+20.43%) ⬆️
sqlite 76.34% <66.66%> (?)
unit 60.72% <100.00%> (+3.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

@fisjac fisjac mentioned this pull request Oct 3, 2024
3 tasks
@fisjac fisjac marked this pull request as ready for review October 3, 2024 23:01
@dosubot dosubot bot added data:connect:googlebigquery Related to BigQuery data:databases Related to database configurations and connections labels Oct 3, 2024
@pull-request-size pull-request-size bot added size/M and removed size/S labels Oct 4, 2024
@michael-s-molina michael-s-molina added v4.1 Label added by the release manager to track PRs to be included in the 4.1 branch and removed review:draft labels Oct 4, 2024

try:
add_permissions(database, ssh_tunnel)
except SupersetDBAPIConnectionError as ex:
Copy link
Member

@Antonio-RiveroMartnez Antonio-RiveroMartnez Oct 4, 2024

Choose a reason for hiding this comment

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

This might occur by other connection errors and not only the credentials one, right? So we would be affecting other engines too and not just BigQuery. Could we instead use the custom_errors in the db_engine_spec and map the credentials one to something we could target individually?

Copy link
Contributor Author

@fisjac fisjac Oct 4, 2024

Choose a reason for hiding this comment

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

Correct, this would affect other DBs. While this bug emerged in the specific case of BigQuery, there are other DBs that may error as well when trying to set up catalogs on import if it's unable to connect. Regardless of the cause of the connection error, be it creds or otherwise, we still shouldn't be blocking the import because it can't connect when looking to add catalogs, 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.

Currently the credentials error for BigQuery is being mapped to the SupersetDBAPIConnectionError

return {DefaultCredentialsError: SupersetDBAPIConnectionError}

Copy link
Member

Choose a reason for hiding this comment

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

Ideally we'd only allow the exception if the database is configured for OAuth2. But even more ideally we'd do what the TODO says, and use CreateDatabaseCommand for the imports, since the command already handles edge cases like this. So I think this is OK for now.

Copy link
Member

@betodealmeida betodealmeida left a comment

Choose a reason for hiding this comment

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

Looks good!

@@ -738,7 +738,7 @@ def _get_fields(cls, cols: list[ResultSetColumnType]) -> list[Any]:
@classmethod
def parse_error_exception(cls, exception: Exception) -> Exception:
try:
return Exception(str(exception).splitlines()[0].strip())
return type(exception)(str(exception).splitlines()[0].strip())
Copy link
Member

Choose a reason for hiding this comment

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

This method parse_error_exception is very confusing... I think it's really unlikely that str(exception).splitlines()[0].strip() will raise an exception — it only happens if str(exception) is '' or if there's some shennanigans in the exception class __str__ method.

I think what the method is trying to do is limit the exception message to the first line, but there are better ways to do that. But it's OK, we can refactor later.

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 issue I was running into was when a mapped SupersetDBAPIError was being passed into this method, it would then be remapped to a base class Exception type with the message preserved. I was trying to preserve the Exception type as well as the message


try:
add_permissions(database, ssh_tunnel)
except SupersetDBAPIConnectionError as ex:
Copy link
Member

Choose a reason for hiding this comment

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

Ideally we'd only allow the exception if the database is configured for OAuth2. But even more ideally we'd do what the TODO says, and use CreateDatabaseCommand for the imports, since the command already handles edge cases like this. So I think this is OK for now.

@fisjac fisjac merged commit 95325c4 into apache:master Oct 4, 2024
40 of 41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data:connect:googlebigquery Related to BigQuery data:databases Related to database configurations and connections size/M v4.1 Label added by the release manager to track PRs to be included in the 4.1 branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants