OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Reverse-spec · Services

octavia — Summary

Reverse-specification of octavia — branch stable/2026.2

  • Repository: https://opendev.org/openstack/octavia (local clone ../octavia) — specified branch: stable/2026.2 @ 2900ed67cac2 (19.0.0-19-g2900ed67, "Delete the VIP port when a load balancer creation fails") — analysed on: 2026-11-01
  • Scope, as agreed: the REST API process in depth (routes, types, validation, errors, policies, DB, provider seam, status and statistics return path, what it needs from Neutron and Keystone) and the rewrite pack (step 8). OpenKeel will serve this API from Go behind the Neutron endpoint, with openkeel-ovn-octavia-provider as its only back end; Python Octavia will not run. The amphora driver and what it brings are out of depth (05 § 3). The change history (step 7) was not requested.
FileContent
01-rest-api_stable-2026.2.mdpipeline, path families, route table, cross-cutting rules, sheets per resource, field tables, policies and RBAC modes, lifecycle
02-errors_stable-2026.2.mdthe three error bodies, translation, catalogue of exceptions with raise sites, provider and asynchronous errors, log messages
03-interactions_stable-2026.2.mddatabase and locks, the provider seam (calls, conversion, status, statistics, get), Neutron, Keystone, Barbican, RabbitMQ
04-scenarios_stable-2026.2.mdLB create, graph create, member batch, cascade delete, failed provider, statistics
05-async-processing_stable-2026.2.mddriver agent; short description of what is out of depth
07-rewrite-pack_stable-2026.2.mdcontents of _rewrite/, conformance format and replay proof, seam mapping to the Go provider, DB strategy, gaps, checklist
_verification_stable-2026.2.mdoutput of the reference checker
_inventory/, _rewrite/raw inventory; machine-readable contracts and conformance data (index: _rewrite/rewrite-pack-index_stable-2026.2.md)

Overview

Octavia's API is a load-balancing control plane with almost no behaviour of its own: it validates a request, records the desired objects in SQL with a PENDING_* status while holding a row lock on the load balancer, and calls a provider driver in-process. It does not move an object out of PENDING_* itself: the provider reports back through Unix-socket status messages handled by a separate process (octavia-driver-agent), which also receives statistics and answers object reads. Network facts come from Neutron, with the caller's token by default. In this codebase the default provider is the amphora driver with its worker, health manager and VMs; none of them applies to OpenKeel, where the load balancers become OVN rows.

Architecture

flowchart LR
  client[openstack CLI, Heat, Magnum, cloud-provider-openstack, Skyline] -->|HTTPS /v2, /v2.0| api[octavia-api: Pecan + WSME]
  api -->|SQL, FOR UPDATE| db[(MariaDB)]
  api -->|token check| ks[Keystone]
  api -->|REST, user token| neutron[Neutron]
  api -->|REST| barbican[Barbican: certificates]
  api -->|in-process call: ProviderDriver| drv[provider driver]
  drv --> ovn[(OVN NB: OVN provider)]
  agent[octavia-driver-agent] -->|SQL| db
  drv2[provider agent or helper] -->|UDS status, stats, get| agent
  amp[amphora driver, worker, health manager]:::out -.->|out of depth| db
  api -.->|RPC cast, amphora routes| amp
  classDef out stroke-dasharray: 4 4;

Processes

ProcessEntry pointRoleListens toIn OpenKeel
octavia-apioctavia/cmd/api.py, octavia/api/app.py:63REST API (port 9876)HTTPGo rewrite, this spec
octavia-driver-agentoctavia/cmd/driver_agent.pystatus, statistics and get sockets; provider agents/var/run/octavia/{status,stats,get}.sockGo rewrite of the sockets (05 § 1)
octavia-db-manageoctavia/db/migration/cli.pyAlembic (95 revisions)CLIreplaced by the migrated DDL
octavia-worker, octavia-health-manager, octavia-housekeeping, amphora-agent, prometheus-proxy…pyproject.toml [project.scripts]amphora driverRabbitMQ, UDP heartbeats, timersnot ported, except the purge of DELETED load balancers (05 § 3)

External dependencies

SystemProtocolLibraryConfigurationUsage
MariaDB/MySQLSQLSQLAlchemy, oslo.db[database] connection39 model tables (41 migrated with alembic_version, spares_pool)
KeystoneHTTPSkeystonemiddleware, keystoneauth[keystone_authtoken], [service_auth], [neutron]token check; service sessions
NeutronHTTPSopenstacksdk[neutron], [networking]VIP and member validation, VIP port for providers that do not make it
BarbicanHTTPSpython-barbicanclient/castellan[certificates] cert_managerTLS refs validation and reading (not needed once the OVN provider refuses TLS, § Points of attention)
RabbitMQAMQPoslo.messagingtransport_urlonly amphora routes and amphora provider; no notification from the API

Key figures

  • Routes: 297 entries: 75 canonical resource operations (69 under four prefixes, 6 amphora under two) + 9 discovery entries (01 § 1.2); 79 canonical in all.
  • Conformance: 991 functional tests run (990 with exchanges, 1 skipped by the project), 8 691 recorded exchanges; replay from data only on the original code: 8 683 identical (8 679 exact + 4 order-insensitive), 8 different, all explained; 3 831 exchanges carry the provider calls they caused, 3 827 of them replayed identical (07 § 7).
  • Seam vectors: 40 status/stats/get cases, 40/40 stable on re-run.
  • Policies: 97 default rules (81 operation rules); matrix of 81 rules × 9 personas × 5 modes.
  • Database: 39 tables in the models, 27 differences with the migrated schema (07 § 5).
  • Errors: 81 exception classes in octavia/common/exceptions.py, 52 reachable from the API scope.

Points of attention

  1. Two validators give two bodies, and Pecan a third: {"faultcode","faultstring","debuginfo"}; {"code","title","description"} (with the odd title: "Bad Request" on a 404 from _lookup); and plain text (healthcheck) (02 § 1). gophercloud and openstacksdk read faultstring.
  2. All resources exist under four prefixes (01 § 1.2), and .xml answers XML.
  3. **The default policy ignores load-balancer_* roles**; deployments that use them need a policy file or enforce_new_defaults=False (01 § 6).
  4. The LB row lock is held across the provider call: the Go provider's driver API must answer quickly, and it must not call back (01 § 3.4).
  5. **A provider that never reports leaves objects PENDING_* for ever**, and everything under the LB immutable: the API has no timeout, the amphora flow's revert does that (03 § 2.3).
  6. **Quota counters decrement only on a DELETED status message** (01 § 4.8).
  7. The VIP port has two owners: the status path deletes it on DELETED only if octavia_owned; the OVN provider does not set that flag and deletes its own port, while a failed creation is cleaned up by the API with its own Neutron credentials (03 § 2.3, 07 § 3).
  8. OVN provider support is narrower than the API: TLS, L7, HM types, algorithms and failover come back as 501 after full API validation, with the provider's text (07 § 3).
  9. 500s to fix deliberately: a body without its root object, a JSON array, unknown flavor profile, listener_id of a missing listener (01 § 3.1).
  10. **listener.insert_headers is a Python pickle** in the database, unreadable from Go (07 § 5).
  11. Message texts contain Python artefacts: list reprs, dictionary reprs, set order. Clients that match them are unlikely [inferred]; the replay normalises them.

Blind spots / [inferred]

  • No real Neutron, Barbican or Keystone was exercised: everything runs with noauth/testing, the noop provider, noop network driver and a mock certificate manager. keystonemiddleware's 401 and token handling come from the code only.
  • The functional tests use SQLite; MariaDB-specific behaviour (deadlocks, SERIALIZABLE flavor delete, SELECT FOR UPDATE contention) comes from reading the code.
  • get_network_ip_availability, allocate_vip were read in octavia/network/drivers/neutron/ but executed only as their noop twins.
  • The provider driver code of octavia-lib (3.12.0 in the venv) and WSME (0.13.0), Pecan (1.8.0) were read without line references: they are not in the workspace.
  • Statements marked [inferred] were deduced without a complete trace or test.

Source: reverse-spec-octavia/00-summary_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.