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

Reverse-spec · Services

octavia — Scenarios

End-to-end scenarios — octavia — branch stable/2026.2

Branch stable/2026.2 @ 2900ed67cac2 — repository https://opendev.org/openstack/octavia — analysed on 2026-11-01

The provider steps show the OpenKeel target: the Go API with the Go provider; statements about the provider come from its specification.

1. Creating a load balancer

The request is complete when the row is PENDING_CREATE; ACTIVE comes later through a status message. The VIP port is made by the provider, inside the transaction.

sequenceDiagram
  autonumber
  actor U as User
  participant API as Octavia API
  participant KS as Keystone
  participant N as Neutron
  participant DB as MariaDB
  participant P as OVN provider
  participant AG as status socket
  U->>API: POST /v2/lbaas/loadbalancers
  API->>KS: validate token (auth_token)
  API->>API: policy loadbalancer:post
  API->>N: GET subnet, port, network, QoS, SG (user token)
  alt not found
    API-->>U: 400 Subnet <id> not found.
  end
  API->>DB: BEGIN, SELECT quotas FOR UPDATE, in_use + 1
  alt over quota
    API-->>U: 403 Quota has been met for resources: load_balancer
  end
  API->>DB: INSERT load_balancer (PENDING_CREATE, OFFLINE), vip
  API->>P: create_vip_port(lb_id, project_id, vip, additional_vips)
  P->>N: POST port
  P-->>API: vip + additional_vips
  API->>DB: UPDATE vip
  API->>P: loadbalancer_create(provider LB)
  alt driver error
    API->>DB: ROLLBACK
    API->>N: DELETE created ports
    API-->>U: 500 / 501 / 409 from call_provider
  else accepted
    API->>DB: COMMIT
    API-->>U: 201 PENDING_CREATE
  end
  P->>AG: {"loadbalancers":[{"id":…,"provisioning_status":"ACTIVE","operating_status":"ONLINE"}]}
  AG->>DB: UPDATE load_balancer
  U->>API: GET …/{id} → ACTIVE

Diagnostics: stuck in PENDING_CREATE → look at the provider and the status socket; 500 with Provider 'ovn' reports error: → provider log.

2. Fully populated load balancer

Same as 1, with step "INSERT" extended by the graph (01 § 4.1).

sequenceDiagram
  autonumber
  participant API as Octavia API
  participant DB as MariaDB
  participant P as OVN provider
  API->>API: move default_pool and redirect_pool definitions to the top level, check names
  API->>DB: quota pools (count), INSERT pools
  loop each pool
    API->>DB: quota HM, INSERT health_monitor; quota members (count), INSERT members
  end
  API->>DB: quota listeners (count), INSERT listeners, sni, cidrs
  loop each listener
    API->>DB: INSERT l7policy, l7rule (no quota)
  end
  API->>P: loadbalancer_create with nested listeners, pools, members
  API->>DB: COMMIT

Diagnostics: the whole tree is one transaction: any 400 leaves nothing, except a port created by the provider, which the failure path deletes.

3. Batch member update

sequenceDiagram
  autonumber
  actor U as User
  participant API as Octavia API
  participant DB as MariaDB
  participant P as OVN provider
  U->>API: PUT /v2/lbaas/pools/{id}/members {members:[…]}
  API->>DB: SELECT LB FOR UPDATE → PENDING_UPDATE; listeners, pool PENDING_UPDATE
  API->>API: diff by (address, port)
  alt nothing to change
    API->>DB: ROLLBACK
    API-->>U: 202
  else
    API->>DB: quota, INSERT new (PENDING_CREATE), UPDATE changed, deleted → PENDING_DELETE
    API->>P: member_batch_update(pool_id, target state)
    API->>DB: COMMIT
    API-->>U: 202
    P-->>DB: statuses per member, DELETED removes the row, quota −1
  end

Diagnostics: additive_only=true keeps absent members and passes them unchanged to the driver.

4. Cascade delete

sequenceDiagram
  autonumber
  actor U as User
  participant API as Octavia API
  participant DB as MariaDB
  participant P as OVN provider
  participant AG as status socket
  U->>API: DELETE /v2/lbaas/loadbalancers/{id}?cascade=true
  API->>DB: SELECT LB FOR UPDATE; status ACTIVE or ERROR → PENDING_DELETE
  alt not deletable
    API-->>U: 409 Invalid state PENDING_UPDATE of loadbalancer resource <id>
  end
  API->>P: loadbalancer_delete(full LB, cascade=true)
  API->>DB: COMMIT
  API-->>U: 204
  P->>AG: listeners, pools, members… DELETED, loadbalancer DELETED
  AG->>DB: quotas −n, DELETE children, LB row stays DELETED

Diagnostics: children stay visible with their old statuses until the provider's message arrives; only the LB's status changes in the request.

5. A provider refusal

sequenceDiagram
  autonumber
  actor U as User
  participant API as Octavia API
  participant DB as MariaDB
  participant P as OVN provider
  U->>API: POST /v2/lbaas/listeners (TERMINATED_HTTPS)
  API->>DB: BEGIN, quota, LB → PENDING_UPDATE, INSERT listener
  API->>API: TLS validation with the certificate manager
  API->>P: listener_create
  P-->>API: UnsupportedOptionError
  API->>DB: ROLLBACK (LB back to ACTIVE, quota restored)
  API-->>U: 501 Provider 'ovn' does not support a requested option: …

Diagnostics: order matters: every API-side validation comes first, including Barbican calls.

6. Statistics

sequenceDiagram
  autonumber
  participant P as OVN provider or any driver
  participant AG as stats socket
  participant DB as MariaDB
  actor U as User
  participant API as Octavia API
  P->>AG: {"listeners":[{"id":…,"bytes_in":…,…}]}
  AG->>DB: upsert listener_statistics (listener_id, amphora_id = listener_id)
  U->>API: GET /v2/lbaas/listeners/{id}/stats
  API->>DB: SELECT listener_statistics
  API-->>U: {"stats":{…}}

Diagnostics: the OVN provider sends no statistics in its current state (provider spec 03), so stats stay at zero: {"stats": {"active_connections":0,…}} even for a listener that never reported [inferred].

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