Tarificación (FinOps): uso recogido de Prometheus, tarificado con reglas hashmap y scripts CEL, historial tarificado en InfluxDB; con openkeel-pricing (presupuestos de coste y de carbono), alimenta la página FinOps / GreenOps de Skyline.
Go Prometheus, InfluxDBopenkeel-cloudkitty
El módulo
OpenKeel implementation in Go of OpenStack CloudKitty, the rating service (cloudkitty-api and cloudkitty-processor), generated from the reverse-specification of branch stable/2026.2 (reverse-spec-cloudkitty/, files 00–07 and _rewrite/) by the generate-go-from-spec skill. It replaces the Python service without its clients noticing (python-cloudkittyclient, cloudkitty-dashboard): same routes (66 operations of v1, hashmap, pyscripts and v2), status codes, WSME and flask-restful error bodies, and policies.
What it does: the processor lists the scopes (Keystone projects with the rating role, Prometheus label values or a static list), collects their usage from Prometheus every period, prices it with the enabled rating modules (hashmap rules, CEL scripts in place of PyScripts), and stores the rated data in InfluxDB (1.x or 2.x); the API manages the rules and returns summaries, rated data frames and instant quotes.
OpenKeel decisions (details and reasons in docs/CONFORMANCE.md):
PyScripts are CEL expressions, evaluated per data point, never Python (exec); tools/pyscript2cel.py translates the scripts written in the documented pattern; skip_datapoints_expression is CEL too.
Collector: Prometheus only (kube-prometheus-stack); storage: InfluxDB only; no RabbitMQ: quotes are computed in the API, scope resets go to the processor through the database; one active processor elected with a Kubernetes Lease.
Fixed upstream defects: scoped deletes, unprotected GET /v2/rating/modules, quotes with a flat desc, InfluxQL built from escaped literals, no unverified Keystone call, reprocessing and reset windows. What is reproduced and what differs is in docs/CONFORMANCE.md; the security checklist is in docs/SECURITY.md.
Go module: github.com/openkeel/openkeel-cloudkitty
Binaries: cloudkitty-api (API on port 8889, health and metrics on 9090) and cloudkitty-processor (health on 9090)
Configuration: YAML, see config/config.example.yaml
Setting up a development environment, the database and the tests: docs/GETTING-STARTED.md
Database schema, migrations and upgrades: docs/DATABASE.md
Extracto de openkeel-cloudkitty/README.md (en inglés).
API REST
66 operaciones de la API REST original (rutas y acciones de cuerpo) y su estado en OpenKeel.
Las tres suites gabbi de CloudKitty se reproducen contra el servicio Go, con vectores hashmap grabados de los tests Python y un despliegue en lab releído a través del ingress.
Replay de los intercambios grabados
Reproducción E2E de las suites gabbi
223 intercambios de 19 ficheros gabbi (v1, hashmap, pyscripts, v2) dan el mismo estado y el mismo cuerpo.
Ejecución
make e2e, también en MariaDB 11.4 (E2E_MYSQL_DSN); el modo estricto pasa con las diferencias conocidas listadas.
Último resultado 153 / 223 idénticos; los otros 70 están explicados (simulaciones de los tests Python, almacenamiento v1, CORS, scripts Python rechazados).
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Tests unitarios y golden tests
Vectores hashmap
24 vectores de tarificación hashmap grabados de cloudkitty.tests.test_hashmap dan el mismo precio al dígito, decimales verificados con CPython.
Ejecución
go test ./... (19 paquetes).
Último resultado 24 / 24 idénticos.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
De extremo a extremo en un laboratorio
Despliegue en lab
Tipo de catálogo rating, módulos, reglas hashmap, presupuestos, un script Python rechazado y uno CEL aceptado, dataframes enviados y releídos por /v2/summary; el processor tarifica desde el inicio del mes.
Ejecución
okadm install --mode lab con cloudkitty, llamadas a través del ingress con un token de administrador; página FinOps / GreenOps de Skyline.
Último resultado Correcto, 0 fallos de tarificación.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Contrato de cliente
Expectativas de los clientes
python-cloudkittyclient, cloudkitty-dashboard y cloudkitty-tempest-plugin.
Ejecución
Aún sin especificación inversa.
Último resultado No ejecutado.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Excluido del rewrite
CloudKitty conserva sus 66 operaciones de API y su tarificación; recoge solo de Prometheus y almacena solo en InfluxDB, y los PyScripts pasan a ser expresiones CEL.
Mecánica interna simplificada
PyScripts (Python ejecutado por el servicio)
Asumido por CEL
Por qué se excluyó
Ejecutar el Python de los operadores con exec es código arbitrario en el servicio; CEL no tiene instrucciones ni E/S, con límites de coste y de tiempo.
Por qué la solución no se ve afectada
La misma tarificación por punto de datos; los scripts escritos según el patrón documentado los traduce tools/pyscript2cel.py, los demás se reescriben.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Asumido por la plataforma Cloud Native
Colectores Gnocchi y Aetos, fetcher Gnocchi
Asumido por Prometheus
Por qué se excluyó
OpenKeel no despliega Gnocchi: el uso viene de Prometheus (kube-prometheus-stack, openstack-exporter).
Por qué la solución no se ve afectada
Los mismos datos tarificados a partir de las métricas de Prometheus; los colectores pueden añadirse bajo demanda.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Asumido por la plataforma Cloud Native
Elasticsearch, OpenSearch, Loki y almacenamiento v1
Asumido por InfluxDB
Por qué se excluyó
El historial tarificado va a InfluxDB 1.x o 2.x; los demás backends no se despliegan.
Por qué la solución no se ve afectada
Resúmenes y dataframes como con el almacenamiento v2; los defectos upstream de filtro de scope de esos backends no pueden ocurrir.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Mecánica interna simplificada
RPC de RabbitMQ y bloqueos tooz
Asumido por Kubernetes Leases
Por qué se excluyó
Los presupuestos se calculan en la API con el mismo código de tarificación; los reinicios de scope llegan al processor por la base de datos; un único processor activo tiene un Lease.
Por qué la solución no se ve afectada
Mismo comportamiento de la API, una dependencia menos, correcto en varios hosts.
Fuente: openkeel-cloudkitty/docs/CONFORMANCE.md
Aquí solo figura lo que se excluyó por diseño; el trabajo aún no realizado está en los Known gaps del docs/CONFORMANCE.md del módulo. Todos los módulos