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

Reverse-spec · Services

magnum — Scenarios

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

Branch stable/2026.2 @ 1910928b7d9f — repository https://opendev.org/openstack/magnum — analysed on 2026-11-09

The scenarios show Magnum core with a generic driver box. For what the Cluster API driver does inside create_cluster, update_cluster_status, resize_cluster and delete_cluster, see the sequence diagrams of 08 § 7.

1. Creating a cluster

Context: a project member creates a cluster from a template. The API validates and answers 202 before anything exists. The conductor creates the rows and certificates and starts the driver. The status poller then waits for the driver to report completion.

sequenceDiagram
  autonumber
  actor U as User
  participant API as magnum-api
  participant KS as Keystone
  participant OS as Glance / Nova / Neutron
  participant MQ as RabbitMQ
  participant C as magnum-conductor
  participant DB as MariaDB
  participant BB as Barbican
  participant D as Driver
  U->>API: POST /v1/clusters (OpenStack-API-Version: container-infra 1.14)
  API->>KS: GET /v3/auth/tokens (keystonemiddleware)
  API->>DB: SELECT cluster_template (or RPC call object_class_action_versions)
  API->>DB: SELECT COUNT(*) FROM cluster WHERE project_id (quota)
  API->>OS: GET flavors (x2), keypair, networks, subnets
  alt validation error
    API-->>U: 400 / 403 / 404 / 409 {"errors":[…]}
  end
  API->>MQ: cast cluster_create (topic magnum-conductor)
  API-->>U: 202 {"uuid"}
  MQ->>C: cluster_create
  C->>DB: INSERT cluster (CREATE_IN_PROGRESS), INSERT nodegroup x2
  C->>BB: POST secrets + containers (3 CAs + client cert)
  C->>MQ: notify magnum.cluster.create (pending)
  C->>D: create_cluster(context, cluster, timeout)
  alt driver or certificate error
    C->>DB: UPDATE cluster SET status=CREATE_FAILED, status_reason
    C->>MQ: notify magnum.cluster.create (failure, priority error)
  else accepted
    C->>DB: UPDATE cluster (stack_id…), UPDATE nodegroup.stack_id
  end
  loop every 10 s (sync_cluster_status)
    C->>DB: SELECT cluster WHERE status IN (*_IN_PROGRESS)
    C->>D: update_cluster_status(cluster)
    D->>DB: UPDATE cluster / nodegroup (status, api_address, coe_version)
  end
  C->>MQ: notify magnum.cluster.create (success | failure)
  U->>API: GET /v1/clusters/{uuid}
  API-->>U: 200 status CREATE_COMPLETE, api_address

Diagnostics:

  • 404 right after the 202: the conductor has not processed the cast yet, or it failed before the insert. Check that a conductor is consuming magnum-conductor and look in its log for the request ID.
  • CREATE_FAILED with "Failed to create certificates for Cluster" (magnum/conductor/handlers/common/cert_manager.py:128): Barbican is unreachable, or the service credentials of [keystone_auth] are wrong.
  • CREATE_FAILED with a driver message: see 08 § 8.
  • Stuck in CREATE_IN_PROGRESS: the driver never reports completion. Magnum core has no timeout on this state, and create_timeout is only passed to the driver.

2. Resizing a nodegroup (manual or cluster-autoscaler)

Context: the cluster-autoscaler running in the cluster, or a user, asks for a new size. Resize is the only operation the conductor accepts while the cluster is already UPDATE_IN_PROGRESS or UPDATE_FAILED.

sequenceDiagram
  autonumber
  actor A as Autoscaler / user
  participant API as magnum-api
  participant MQ as RabbitMQ
  participant C as magnum-conductor
  participant DB as MariaDB
  participant D as Driver
  A->>API: POST /v1/clusters/{id}/actions/resize {"node_count":5,"nodegroup":"workers-b"}
  API->>DB: SELECT cluster, nodegroup
  alt outside [min_node_count, max_node_count]
    API-->>A: 400 NGResizeOutBounds
  else master nodegroup
    API->>D: validate_master_resize(5)
  end
  API->>MQ: cast cluster_resize
  API-->>A: 202 {"uuid"}
  MQ->>C: cluster_resize
  alt cluster status not in allowed list
    C--xC: NotSupported (logged only)
  end
  C->>DB: UPDATE nodegroup SET node_count=5, status=UPDATE_IN_PROGRESS
  C->>D: resize_cluster(cluster, manager, 5, nodes_to_remove, nodegroup)
  alt driver error
    C->>DB: cluster+nodegroup UPDATE_FAILED, node_count restored
  else accepted
    C->>DB: cluster UPDATE_IN_PROGRESS
  end
  loop every 10 s
    C->>D: update_cluster_status
  end

Diagnostics: an autoscaler that keeps getting 202 while nothing happens usually means the cluster is in a state the conductor refuses (CREATE_FAILED, DELETE_*). The refusal only appears in the conductor log, as NotSupported "Resizing a cluster when status is …" (magnum/conductor/handlers/cluster_conductor.py:221).

3. Upgrading a cluster

Context: the user moves the cluster to a template with a newer kube_tag. This is the only cluster action where the HTTP request waits for the conductor and the driver.

sequenceDiagram
  autonumber
  actor U as User
  participant API as magnum-api
  participant MQ as RabbitMQ
  participant C as magnum-conductor
  participant D as Driver
  U->>API: POST /v1/clusters/{id}/actions/upgrade {"cluster_template":"k8s-1.32","max_batch_size":1}
  API->>MQ: call cluster_upgrade (waits, rpc_response_timeout)
  MQ->>C: cluster_upgrade
  alt status not *_COMPLETE
    C-->>API: NotSupported
    API-->>U: 400 "Upgrading a cluster when status is …"
  else
    C->>D: upgrade_cluster(cluster, template, max_batch_size, nodegroup)
    alt driver raises NotSupported
      C-->>API: NotSupported (statuses unchanged)
      API-->>U: 400
    else other error
      C->>C: cluster + nodegroup UPDATE_FAILED
      C-->>API: exception
      API-->>U: 4xx/500
    else accepted
      C->>C: cluster + nodegroup UPDATE_IN_PROGRESS
      C-->>API: cluster
      API-->>U: 202 {"uuid"}
    end
  end

Diagnostics: a 500 after about 60 s is an RPC timeout (rpc_response_timeout). The driver may still finish the upgrade in the background. Check the cluster status before retrying.

4. Deleting a cluster

Context: the user deletes a cluster. The 204 is returned before anything is removed. The row disappears only when the poller sees DELETE_COMPLETE from the driver.

sequenceDiagram
  autonumber
  actor U as User
  participant API as magnum-api
  participant MQ as RabbitMQ
  participant C as magnum-conductor
  participant DB as MariaDB
  participant BB as Barbican
  participant D as Driver
  U->>API: DELETE /v1/clusters/{id}
  API->>MQ: cast cluster_delete
  API-->>U: 204
  MQ->>C: cluster_delete
  C->>D: delete_cluster(cluster)
  alt error
    C->>DB: UPDATE cluster SET status=DELETE_FAILED
  else
    C->>DB: UPDATE cluster SET status=DELETE_IN_PROGRESS
  end
  loop every 10 s
    C->>D: update_cluster_status
    D->>DB: status = DELETE_COMPLETE (when the back end is gone)
  end
  C->>BB: DELETE Kubernetes CA + client cert containers
  C->>DB: DELETE nodegroup (each), DELETE cluster
  C->>MQ: notify magnum.cluster.delete (success)

Diagnostics: a cluster stuck in DELETE_IN_PROGRESS means the driver's back end has not finished the teardown. With the CAPI driver, typical causes are finalizers on OpenStack resources or a load balancer left by the cloud controller manager (see 08). The etcd and front-proxy CA secrets remain in Barbican after deletion.

5. Getting a kubeconfig (certificates)

Context: openstack coe cluster config builds a kubeconfig. It downloads the cluster CA, generates a key and CSR on the client side, and has the CA sign it.

sequenceDiagram
  autonumber
  actor U as openstack coe cluster config
  participant API as magnum-api
  participant C as magnum-conductor
  participant BB as Barbican
  U->>API: GET /v1/clusters/{id}
  U->>API: GET /v1/certificates/{id}
  API->>C: call get_ca_certificate
  C->>BB: GET container + payloads (CA)
  C-->>API: pem
  API-->>U: 200 {"pem": CA}
  U->>U: generate key + CSR (CN=user, O=…)
  U->>API: POST /v1/certificates {"cluster_uuid", "csr"}
  API->>C: call sign_certificate
  C->>BB: GET CA key + passphrase
  C->>C: x509.sign (allowed extensions, 5-year validity)
  C-->>API: pem
  API-->>U: 201 {"pem"}

Diagnostics: a 400 CertificateValidationError means the CSR asks for an extension or key usage that [x509]/allowed_extensions or allowed_key_usage refuses. A 500 usually means Barbican is unreachable. With the CAPI driver, Magnum's CAs are also the kubeadm CAs (08 § 6), so the signed certificate is valid for the Kubernetes API.

6. Health status

sequenceDiagram
  autonumber
  participant C as magnum-conductor (parent)
  participant DB as MariaDB
  participant BB as Barbican / cache dir
  participant K as Cluster Kubernetes API
  loop every [kubernetes]/health_polling_interval (60 s)
    C->>DB: SELECT cluster WHERE status IN (9 states)
    C->>C: driver.get_monitor(cluster)
    alt auto_healing_controller = magnum-auto-healer
      C->>C: skip (the in-cluster healer PATCHes health)
    else API not publicly reachable
      C->>DB: health_status = UNKNOWN
    else
      C->>BB: read CA + client cert (or cached files)
      C->>K: GET /healthz, GET /api/v1/nodes (mTLS, no timeout)
      C->>DB: health_status HEALTHY | UNHEALTHY, reason {node.Ready…, api}
    end
  end

Diagnostics: UNKNOWN with "is not accessible" is expected for clusters without a floating IP on their API. A health status that never changes usually comes from a monitor exception, which the conductor logs as a warning.

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