fixeria has uploaded this change for review.

View Change

doc/manuals: document the REST interface

Change-Id: I8bc9183fff8f65db71554ee26369db9bdb61b78a
Related: OS#6671
---
M doc/manuals/chapters/metrics.adoc
M doc/manuals/chapters/overview.adoc
A doc/manuals/chapters/rest.adoc
M doc/manuals/osmo-s1gw-usermanual.adoc
4 files changed, 338 insertions(+), 3 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/67/42367/1
diff --git a/doc/manuals/chapters/metrics.adoc b/doc/manuals/chapters/metrics.adoc
index 5b81227..963e303 100644
--- a/doc/manuals/chapters/metrics.adoc
+++ b/doc/manuals/chapters/metrics.adoc
@@ -155,7 +155,8 @@

When an MME is registered in the pool — either at startup from the
configuration file (see <<config_mme_pool>>) or dynamically via the REST
-API — OsmoS1GW creates a set of per-MME counters scoped to that MME entry.
+API (see <<rest_mme>>) — OsmoS1GW creates a set of per-MME counters
+scoped to that MME entry.

The naming scheme is `mme.{name}.{suffix}`, where `{name}` is the MME's
configured name (e.g. `mme0`).
diff --git a/doc/manuals/chapters/overview.adoc b/doc/manuals/chapters/overview.adoc
index d8248ca..d91b466 100644
--- a/doc/manuals/chapters/overview.adoc
+++ b/doc/manuals/chapters/overview.adoc
@@ -63,9 +63,9 @@
provisioned statically via the configuration file or dynamically via
the REST API.
* *`enb_registry`* — Tracks all active eNB connections and their state.
- Queryable via the REST API.
+ Queryable via the REST API (see <<rest_enb>>).
* *`rest_server`* — OpenAPI-based HTTP REST interface for monitoring and
- management.
+ management (see <<rest>>).

[[use_cases]]
=== Use Cases
diff --git a/doc/manuals/chapters/rest.adoc b/doc/manuals/chapters/rest.adoc
new file mode 100644
index 0000000..e1fb324
--- /dev/null
+++ b/doc/manuals/chapters/rest.adoc
@@ -0,0 +1,332 @@
+[[rest]]
+== REST Interface
+
+OsmoS1GW exposes an HTTP REST API for monitoring and management. The
+API follows the OpenAPI 3.0 specification; the full machine-readable spec
+is served at `GET /openapi.json`. A Swagger UI is available at
+`/swagger` when enabled (see <<config_rest>>).
+
+By default the REST server listens on port `8080`. No authentication is
+implemented; access control should be enforced at the network level if
+required.
+
+[[rest_identifiers]]
+=== Resource Identifiers
+
+Several endpoints accept a resource identifier in the URL path that can
+be expressed in multiple forms:
+
+[[rest_mme_id]]
+==== MME Identifier (`{MmeId}`)
+
+[options="header",cols="25,35,40"]
+|===
+| Form | Pattern | Example
+| Name | `name:<name>` | `name:mme0`
+| Address/port | `addr:<ip>-<port>` | `addr:192.168.1.1-36412`
+|===
+
+[[rest_enb_id]]
+==== eNB Identifier (`{EnbId}`)
+
+[options="header",cols="25,35,40"]
+|===
+| Form | Pattern | Example
+| Registry handle | `handle:<n>` | `handle:42`
+| Process ID | `pid:<x>.<y>.<z>` | `pid:0.33.1`
+| Global-eNB-ID | `genbid:<mcc>-<mnc>-<id>` | `genbid:999-70-1337`
+| eNB SCTP assoc ID | `enb-sctp-aid:<n>` | `enb-sctp-aid:42`
+| MME SCTP assoc ID | `mme-sctp-aid:<n>` | `mme-sctp-aid:42`
+| eNB connection addr | `enb-conn:<ip>-<port>` | `enb-conn:192.168.1.1-34650`
+|===
+
+[[rest_erab_id]]
+==== E-RAB Identifier (`{ErabId}`)
+
+[options="header",cols="25,35,40"]
+|===
+| Form | Pattern | Example
+| Process ID | `pid:<x>.<y>.<z>` | `pid:0.33.1`
+|===
+
+[[rest_metrics]]
+=== Metrics
+
+[[rest_metrics_list]]
+==== `GET /metrics-list` — List Metrics
+
+Returns a list of all matching metrics with their current values.
+
+Query parameters:
+
+`type`::
+ Filter by metric type. One of `all` (default), `counter`, or `gauge`.
+
+`path`::
+ Filter by metric name prefix (dot-separated). For example, `s1ap.proxy`
+ returns all metrics whose name starts with `s1ap.proxy`.
+
+Response (HTTP 200):
+
+----
+[
+ {"type": "counter", "name": "pfcp.heartbeat_req.tx", "value": 42},
+ {"type": "counter", "name": "pfcp.heartbeat_req.timeout", "value": 0},
+ {"type": "gauge", "name": "pfcp.associated", "value": 1}
+]
+----
+
+Returns HTTP 404 if no metrics match the given filter.
+
+See <<metrics>> for the full list of metric names.
+
+[[rest_pfcp]]
+=== PFCP
+
+[[rest_pfcp_assoc]]
+==== `GET /pfcp/assoc` — PFCP Association State
+
+Returns the current PFCP association state between OsmoS1GW and the UPF.
+
+Response (HTTP 200):
+
+----
+{
+ "state": "connected",
+ "laddr": "127.0.1.1",
+ "raddr": "127.0.1.2",
+ "lrts": 3967211233,
+ "rrts": 3965211123
+}
+----
+
+`state`:: Current association state: `connecting` or `connected`.
+`laddr`:: Local PFCP bind address.
+`raddr`:: Remote UPF address.
+`lrts`:: Local Recovery Timestamp.
+`rrts`:: Remote Recovery Timestamp (present only when associated).
+
+==== `POST /pfcp/assoc` — Initiate PFCP Association Setup
+
+Triggers an immediate PFCP Association Setup Request to the UPF.
+Returns an `OperationResult` object indicating success or failure.
+
+==== `DELETE /pfcp/assoc` — Release PFCP Association
+
+Initiates a PFCP Association Release procedure.
+Returns an `OperationResult` object.
+
+==== `POST /pfcp/heartbeat` — Send PFCP Heartbeat
+
+Sends a PFCP Heartbeat Request to the UPF and waits for the response.
+Returns an `OperationResult` object.
+
+[[rest_mme]]
+=== MME Pool
+
+[[rest_mme_list]]
+==== `GET /mme-list` — List MMEs
+
+Returns the current contents of the MME pool.
+
+Response (HTTP 200):
+
+----
+[
+ {"name": "mme0", "laddr": "::", "raddr": "192.168.2.10", "rport": 36412, "tac_list": []},
+ {"name": "mme1", "laddr": "::", "raddr": "192.168.2.20", "rport": 36412, "tac_list": [100, 101]}
+]
+----
+
+[[rest_mme_add]]
+==== `POST /mme-list` — Add MME
+
+Adds a new MME to the pool. The request body is a JSON object with the
+same fields as the entries returned by `GET /mme-list`:
+
+`name` (required):: Unique human-readable name.
+`raddr` (required):: Remote IP address of the MME.
+`laddr` (optional):: Local bind address. Default: `"::"` (any).
+`rport` (optional):: Remote SCTP port. Default: `36412`.
+`tac_list` (optional):: List of TACs this MME serves. Default: `[]` (all).
+
+Returns HTTP 201 on success, HTTP 409 if the name or address is already
+registered.
+
+[[rest_mme_info]]
+==== `GET /mme/{MmeId}` — MME Info
+
+Returns configuration details for a single MME. The response format is
+the same as a single element from `GET /mme-list`.
+
+Returns HTTP 404 if no matching MME is found.
+
+[[rest_mme_delete]]
+==== `DELETE /mme/{MmeId}` — Delete MME
+
+Removes an MME from the pool. Active connections to this MME are not
+affected; the change only prevents the MME from being selected for future
+connection attempts.
+
+Returns HTTP 200 on success, HTTP 404 if no matching MME is found.
+
+[[rest_enb]]
+=== eNB Connections
+
+[[rest_enb_list]]
+==== `GET /enb-list` — List eNB Connections
+
+Returns a list of all currently connected eNBs.
+
+Response (HTTP 200):
+
+----
+[
+ {
+ "handle": 0,
+ "pid": "<0.699.0>",
+ "genb_id": "001-01-0",
+ "state": "connected",
+ "enb_saddr": "192.168.1.10",
+ "enb_sport": 56767,
+ "enb_sctp_aid": 5706,
+ "mme_daddr": "192.168.2.10",
+ "mme_dport": 36412,
+ "mme_sport": 34500,
+ "mme_sctp_aid": 5707,
+ "uptime": 418,
+ "erab_count": 3
+ }
+]
+----
+
+`handle`:: Unique integer identifier within the eNB registry.
+`pid`:: Erlang process ID of the `enb_proxy` process.
+`genb_id`:: Global-eNB-ID in MCC-MNC-eNBId format. Present once the S1
+ Setup procedure has completed.
+`state`:: Current proxy state: `wait_s1setup_req`, `connecting`,
+ `wait_s1setup_rsp`, or `connected`.
+`enb_saddr` / `enb_sport`:: Source address and port of the eNB's SCTP connection.
+`enb_sctp_aid`:: SCTP association ID of the eNB-S1GW connection.
+`mme_daddr` / `mme_dport`:: Destination address and port of the MME.
+`mme_sport`:: Local source port of the S1GW-MME SCTP connection.
+`mme_sctp_aid`:: SCTP association ID of the S1GW-MME connection.
+`uptime`:: Seconds since the eNB connected.
+`erab_count`:: Number of currently active E-RABs for this eNB.
+
+==== `GET /enb/{EnbId}` — eNB Info
+
+Returns details for a single eNB. The response format is the same as a
+single element from `GET /enb-list`.
+
+Returns HTTP 404 if no matching eNB is found.
+
+==== `DELETE /enb/{EnbId}` — Force Disconnect eNB
+
+Forcibly terminates the SCTP connection to the specified eNB. This
+causes the eNB to reconnect and restart the S1 Setup procedure.
+
+Returns HTTP 200 on success, HTTP 404 if no matching eNB is found.
+
+[[rest_erab]]
+=== E-RAB Bearers
+
+==== `GET /erab-list` — List All E-RABs
+
+Returns a list of all active E-RABs across all connected eNBs.
+
+==== `GET /enb/{EnbId}/erab-list` — List E-RABs for an eNB
+
+Returns all active E-RABs for a specific eNB.
+
+Returns HTTP 404 if no matching eNB is found.
+
+The response for both list endpoints is an array of E-RAB objects (same
+format as `GET /erab/{ErabId}`).
+
+==== `GET /erab/{ErabId}` — E-RAB Info
+
+Returns details for a single E-RAB.
+
+Response (HTTP 200):
+
+----
+{
+ "pid": "<0.714.0>",
+ "mme_ue_id": 4242,
+ "erab_id": 1,
+ "state": "erab_setup",
+ "pfcp_lseid": 2,
+ "pfcp_rseid": 6076548759901618177,
+ "f_teid_u2c": {"teid": 65537, "tla": "127.0.0.1"},
+ "f_teid_c2u": {"teid": 16842753, "tla": "127.0.1.1"},
+ "f_teid_a2u": {"teid": 33686529, "tla": "127.0.2.2"},
+ "f_teid_u2a": {"teid": 131073, "tla": "127.0.0.2"}
+}
+----
+
+`pid`:: Erlang process ID of the `erab_fsm` process.
+`mme_ue_id`:: MME-UE-S1AP-ID.
+`erab_id`:: E-RAB-ID.
+`state`:: Current FSM state.
+`pfcp_lseid` / `pfcp_rseid`:: Local and remote PFCP SEIDs.
+`f_teid_u2c`:: GTP-U F-TEID for UPF → Core direction.
+`f_teid_c2u`:: GTP-U F-TEID for Core → UPF direction.
+`f_teid_a2u`:: GTP-U F-TEID for Access (eNB) → UPF direction.
+`f_teid_u2a`:: GTP-U F-TEID for UPF → Access (eNB) direction.
+
+Each F-TEID object has a `teid` (integer) and a `tla` (Transport Layer
+Address, dotted IP string).
+
+==== `DELETE /erab/{ErabId}` — Terminate E-RAB
+
+Forcibly terminates the `erab_fsm` process for the given E-RAB. This
+triggers PFCP Session Deletion towards the UPF. Use with caution on
+live connections.
+
+Returns HTTP 200 on success, HTTP 404 if no matching E-RAB is found.
+
+[[rest_cli]]
+=== Interactive CLI (`osmo-s1gw-cli`)
+
+`osmo-s1gw-cli` is an interactive command-line shell built on Python's
+https://cmd2.readthedocs.io/[cmd2] library. It provides a convenient
+alternative to issuing raw HTTP requests, with tab-completion, filtering
+(`CMD | grep ...`), and output redirection (`CMD > FILE`).
+
+After installation, the CLI is available as `osmo-s1gw-cli`. It
+communicates with OsmoS1GW via the REST interface.
+
+----
+osmo-s1gw-cli [-h] [-v] [-p PORT] [HOST]
+
+ HOST OsmoS1GW REST host/address (default: localhost)
+ -p REST port (default: 8080)
+ -v Enable verbose/debug logging
+----
+
+Available commands can be listed within the shell using `help -v`, and
+per-command help is available with `help <command>`. The following
+commands are supported:
+
+[options="header",cols="30,70"]
+|===
+| Command | Description
+| `fetch_openapi_spec` | Fetch and display the OpenAPI specification
+| `metrics_list` | List metrics, optionally filtered by type and/or name path
+| `pfcp_assoc_state` | Display the PFCP association state
+| `pfcp_heartbeat` | Send a PFCP Heartbeat Request
+| `mme_list` | List registered MMEs
+| `mme_add` | Add an MME to the pool
+| `mme_info` | Show details for a specific MME
+| `mme_delete` | Remove an MME from the pool
+| `enb_list` | List connected eNBs
+| `enb_info` | Show details for a specific eNB
+| `enb_delete` | Force-disconnect an eNB
+| `enb_erab_list` | List E-RABs for a specific eNB
+| `erab_list` | List all E-RABs across all eNBs
+| `erab_info` | Show details for a specific E-RAB
+| `erab_delete` | Terminate an E-RAB FSM process
+|===
+
+// vim:set ts=4 sw=4 et:
diff --git a/doc/manuals/osmo-s1gw-usermanual.adoc b/doc/manuals/osmo-s1gw-usermanual.adoc
index 2427d31..c565911 100644
--- a/doc/manuals/osmo-s1gw-usermanual.adoc
+++ b/doc/manuals/osmo-s1gw-usermanual.adoc
@@ -19,6 +19,8 @@

include::{srcdir}/chapters/gtpu_kpi.adoc[]

+include::{srcdir}/chapters/rest.adoc[]
+
include::{commondir}/chapters/glossary.adoc[]

include::{commondir}/chapters/bibliography.adoc[]

To view, visit change 42367. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I8bc9183fff8f65db71554ee26369db9bdb61b78a
Gerrit-Change-Number: 42367
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>