feat(infra): auto-commit con 56 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 14:22:55 +02:00
parent c1071a82b3
commit 32c7336bf6
56 changed files with 5307 additions and 100 deletions
@@ -0,0 +1,59 @@
---
name: parse_metabase_secret
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: pure
signature: "def parse_metabase_secret(secret_text: str, mode: str = 'auto') -> dict"
description: "Parser puro que extrae credenciales de Metabase del texto crudo de un secreto de pass. Distingue API-key (una sola linea, p.ej. mb_... de metabase/aurgi-api-key) de sesion (multi-linea estilo captacion/metabase: primera linea password, linea email:/user:/login:/username: con el usuario). mode='auto' detecta el formato; mode='api_key' o 'session' fuerzan. No hace I/O. Devuelve dict {status, mode, api_key} o {status, mode, email, password} o {status:error, error}. Nunca lanza ni logea el secreto."
tags: [metabase, pass, secret, credential, parse, pure]
uses_functions: []
uses_types: []
params:
- name: secret_text
desc: "Contenido completo del secreto leido de pass (varias lineas separadas por \\n). Primera linea = password/clave por convencion de pass; lineas siguientes = metadata."
- name: mode
desc: "'api_key', 'session' o 'auto' (default). En auto: si hay linea email/usuario reconocible -> session; si no -> api_key."
output: "Dict. api_key: {status:'ok', mode:'api_key', api_key:str}. session: {status:'ok', mode:'session', email:str, password:str}. error: {status:'error', error:str} para texto vacio, modo invalido o session sin email/password."
returns: []
returns_optional: false
error_type: ""
imports: []
tested: true
tests: ["test_api_key_explicit", "test_session_multiline_email_prefix", "test_auto_detects_session_when_email_present", "test_auto_detects_api_key_single_line", "test_session_without_email_line_errors", "test_empty_secret_errors", "test_invalid_mode_errors", "test_user_prefix_variant", "test_email_value_preserves_case"]
test_file_path: "python/functions/metabase/parse_metabase_secret_test.py"
file_path: "python/functions/metabase/parse_metabase_secret.py"
---
## Ejemplo
```python
import sys
sys.path.insert(0, "python/functions")
from metabase.parse_metabase_secret import parse_metabase_secret
# API-key (una sola linea):
parse_metabase_secret("mb_abc123")
# {'status': 'ok', 'mode': 'api_key', 'api_key': 'mb_abc123'}
# Sesion (multi-linea estilo captacion/metabase):
parse_metabase_secret("hunter2\nemail: a@b.com\nurl: http://x")
# {'status': 'ok', 'mode': 'session', 'email': 'a@b.com', 'password': 'hunter2'}
```
## Cuando usarla
Cuando ya tienes el texto de un secreto de Metabase (leido de `pass` u otra
fuente) y necesitas separarlo en credenciales utilizables sin tocar disco ni
red. Es el nucleo puro y testeable de `metabase_client_from_pass`: separa el
parseo (determinista) de la lectura del secreto y la autenticacion (impuras).
## Gotchas
- La linea del email/usuario se identifica por prefijo: `email:`, `login:`,
`username:` o `user:` (case-insensitive). Otros formatos no se detectan como
sesion y `auto` los tratara como api_key.
- Funcion pura: NO lee `pass` ni llama a Metabase. El caller le pasa el texto ya
resuelto. No logea el secreto, pero el dict de retorno SI lleva el valor en
claro — el caller debe tratarlo como sensible.