refactor(proxy-extras): drop the spend-log api_key special case from the row check remedy (#48636)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Kerry Lu 2026-10-27 13:53:23 -07:00 • committed by GitHub
parent 34c10829b1
commit 52562c47f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 7 additions and 12 deletions

View file

@ -42,12 +42,6 @@ _OCTET_LENGTH_TYPES: Final = frozenset({"text", "varchar", "bpchar", "bytea", "n
MIGRATION_DATA_CHECK_TIMEOUT_ENV_VAR: Final = "LITELLM_MIGRATION_DATA_CHECK_TIMEOUT"
DEFAULT_MIGRATION_DATA_CHECK_TIMEOUT_SECONDS: Final = 600.0
REFUSAL: Final = "Existing rows would make a pending schema change fail:"
LEGACY_SPEND_LOG_KEY_REMEDY: Final = (
"Rows written before v1.99.0 hold the raw key. Hash them in place (one-way, idempotent):\n"
' UPDATE "LiteLLM_SpendLogs" SET api_key = encode(sha256(convert_to('
"regexp_replace(api_key, '^[Bb][Ee][Aa][Rr][Ee][Rr] ', ''), 'UTF8')), 'hex')\n"
" WHERE api_key <> '' AND api_key !~ '^[0-9a-fA-F]{64}$' AND api_key !~ '^hashed-jwt-[0-9A-Fa-f]{64}$';"
)
Kind = Literal["too_long", "duplicates", "nulls", "any_row", "orphans", "check_violations"]
@ -571,8 +565,6 @@ def find_blockers(
def _remedy(check: Check) -> str:
if check.kind == "too_long" and check.table == "LiteLLM_SpendLogs" and "api_key" in check.columns:
return LEGACY_SPEND_LOG_KEY_REMEDY
joined: Final = ", ".join(check.columns)
match check.kind:
case "too_long":

View file

@ -956,8 +956,11 @@ def _legacy_bearer_token() -> str:
return "Bearer " + secrets.token_hex(1600)
def _hash_sql_from(refusal: str) -> str:
return refusal[refusal.index('UPDATE "LiteLLM_SpendLogs"') : refusal.index("{64}$';") + len("{64}$';")]
_HASH_LEGACY_KEYS: Final = (
'UPDATE "LiteLLM_SpendLogs" SET api_key = encode(sha256(convert_to('
"regexp_replace(api_key, '^[Bb][Ee][Aa][Rr][Ee][Rr] ', ''), 'UTF8')), 'hex') "
"WHERE api_key <> '' AND api_key !~ '^[0-9a-fA-F]{64}$' AND api_key !~ '^hashed-jwt-[0-9A-Fa-f]{64}$'"
)
@requires_db
@ -985,7 +988,7 @@ def test_the_migration_job_refuses_before_the_first_migration_when_spend_log_key
assert API_KEY_INDEX not in _index_validity(scratch_database, "api_key_startTime_idx")
with psycopg.connect(scratch_database, autocommit=True) as conn:
conn.execute(_hash_sql_from(refusal)) # pyright: ignore[reportArgumentType] # the refusal's own SQL
conn.execute(_HASH_LEGACY_KEYS)
assert ProxyExtrasDBManager.run_migration_job(use_migrate=True, use_v2_resolver=use_v2_resolver) is True
assert _index_validity(scratch_database, "api_key_startTime_idx") == {API_KEY_INDEX: True}
assert len(_ledger(scratch_database)) > len(ledger_before)

View file

@ -125,7 +125,7 @@ def test_the_report_names_the_rows_the_statement_and_the_fix_and_says_nothing_wa
"(api_key up to 3207 bytes)"
) in text
assert 'blocks: CREATE INDEX "LiteLLM_SpendLogs_api_key_startTime_idx" (request-log index)' in text
assert 'UPDATE "LiteLLM_SpendLogs" SET api_key = encode(sha256(' in text
assert 'fix: Shorten or hash the long "LiteLLM_SpendLogs" (api_key, startTime) values' in text
assert text.startswith("Existing rows would make a pending schema change fail:")
assert "No schema change was made" in text