villebro opened a new pull request, #40079:
URL: https://github.com/apache/superset/pull/40079

   ### SUMMARY
     Fixes several issues in superset re-encrypt-secrets that surfaced with the 
addition of the semantic_layers table (PK = uuid, with an encrypted 
configuration column):
   
   - Works on tables without an integer id PK. SecretsMigrator previously 
hardcoded `SELECT id, ... FROM <table> and WHERE id = :id`. It now derives the 
actual primary key column(s) from the Table metadata, so tables like 
`semantic_layers` (whose PK is `uuid`) can be rotated without error.
   - Idempotent re-runs. Re-encryption now checks whether the current key can 
already decrypt each value and skips if so, regardless of what 
previous_secret_key is supplied. Previously the check order was reversed, so 
re-running with a previous key that still happened to decrypt (e.g. after a 
successful rotation, or accidentally passing the current key as "previous") 
would re-encrypt every value on every run.
   - Per-column outcome summary. run() logs and returns a 
ReEncryptStats(re_encrypted, skipped, null, failed) count at the end of the 
flow. `NULL` values are counted separately from "already current" skips so 
operators can tell them apart. On failure, the transaction rolls back and the 
count of failed values is surfaced.
   - Cleaner CLI exit codes.
     - Missing `PREVIOUS_SECRET_KEY` → exit 0 with a yellow "nothing to 
re-encrypt" notice (was exit 1). This lets scheduled rotation scripts run 
unconditionally after a rotation is complete without starting to fail.
     - Any failed field → exit 1 with a formatted "Re-encryption failed: ..." 
message (was a partial catch on ValueError only, letting generic exceptions 
leak as uncaught tracebacks).
     - Successful run → prints the stats summary in green.
   
   ### BEFORE
   ```
   2026-05-12 15:55:27,891:INFO:superset.utils.encrypt:Collecting info for re 
encryption
   
   2026-05-12 15:55:27,891:INFO:superset.utils.encrypt:Processing table: dbs
   Traceback (most recent call last):
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py",
 line 1910, in _execute_context
       self.dialect.do_execute(
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/default.py",
 line 736, in do_execute
       cursor.execute(statement, parameters)
   sqlite3.OperationalError: no such column: id
   
   The above exception was the direct cause of the following exception:
   
   Traceback (most recent call last):
     File "/Users/ville/projects/superset/venv/bin/superset", line 6, in 
<module>
       sys.exit(superset())
                ^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/core.py",
 line 1442, in __call__
       return self.main(*args, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/core.py",
 line 1363, in main
       rv = self.invoke(ctx)
            ^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/core.py",
 line 1830, in invoke
       return _process_result(sub_ctx.command.invoke(sub_ctx))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/core.py",
 line 1226, in invoke
       return ctx.invoke(self.callback, **ctx.params)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/core.py",
 line 794, in invoke
       return callback(*args, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/decorators.py",
 line 34, in new_func
       return f(get_current_context(), *args, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/flask/cli.py",
 line 358, in decorator
       return __ctx.invoke(f, *args, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/click/core.py",
 line 794, in invoke
       return callback(*args, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
     File "/Users/ville/projects/superset/superset/cli/update.py", line 122, in 
re_encrypt_secrets
       secrets_migrator.run()
     File "/Users/ville/projects/superset/superset/utils/encrypt.py", line 218, 
in run
       rows = self._select_columns_from_table(conn, column_names, table_name)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File "/Users/ville/projects/superset/superset/utils/encrypt.py", line 156, 
in _select_columns_from_table
       return conn.execute(f"SELECT id, {','.join(column_names)} FROM 
{table_name}")  # noqa: S608
              
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py",
 line 1370, in execute
       return self._exec_driver_sql(
              ^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py",
 line 1674, in _exec_driver_sql
       ret = self._execute_context(
             ^^^^^^^^^^^^^^^^^^^^^^
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py",
 line 1953, in _execute_context
       self._handle_dbapi_exception(
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py",
 line 2134, in _handle_dbapi_exception
       util.raise_(
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/util/compat.py",
 line 211, in raise_
       raise exception
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py",
 line 1910, in _execute_context
       self.dialect.do_execute(
     File 
"/Users/ville/projects/superset/venv/lib/python3.11/site-packages/sqlalchemy/engine/default.py",
 line 736, in do_execute
       cursor.execute(statement, parameters)
   sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: 
id
   [SQL: SELECT id, configuration FROM semantic_layers]
   (Background on this error at: https://sqlalche.me/e/14/e3q8)
   ```
   
   ### AFTER
   Successful rotation:
   ```
   2026-05-12 16:26:17,793:INFO:superset.utils.encrypt:Collecting info for re 
encryption
   2026-05-12 16:26:17,794:INFO:superset.utils.encrypt:Re-encryption summary: 2 
re-encrypted, 0 skipped, 4 null, 0 failed
   2026-05-12 16:26:17,794:INFO:superset.utils.encrypt:All tables processed
   Re-encryption complete: 2 re-encrypted, 0 skipped, 4 null, 0 failed.
   ```
   
   No-op (SECRET_KEY already decrypts values successfully):
   ```
   2026-05-12 16:27:59,631:INFO:superset.utils.encrypt:Collecting info for re 
encryption
   2026-05-12 16:27:59,634:INFO:superset.utils.encrypt:Re-encryption summary: 0 
re-encrypted, 2 skipped, 4 null, 0 failed
   2026-05-12 16:27:59,634:INFO:superset.utils.encrypt:All tables processed
   Re-encryption complete: 0 re-encrypted, 2 skipped, 4 null, 0 failed.
   ```
   
   Invalid secrets (neither `SECRET_KEY` nor `PREVIOUS_SECRET_KEY` decrypts 
current values):
   ```
   2026-05-12 16:29:35,246:INFO:superset.utils.encrypt:Collecting info for re 
encryption
   2026-05-12 16:29:35,247:ERROR:superset.utils.encrypt:Column [dbs.password] 
cannot be decrypted under the previous or current secret key (ValueError: 
Invalid decryption key)
   2026-05-12 16:29:35,247:ERROR:superset.utils.encrypt:Column 
[dbs.encrypted_extra] cannot be decrypted under the previous or current secret 
key (ValueError: Invalid decryption key)
   2026-05-12 16:29:35,248:INFO:superset.utils.encrypt:Re-encryption summary: 0 
re-encrypted, 0 skipped, 4 null, 2 failed
   Re-encryption failed: Re-encryption failed for 2 value(s); transaction 
rolled back
   ```
   
   ### ADDITIONAL INFORMATION
   <!--- Check any relevant boxes with "x" -->
   <!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] 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
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to