fixeria has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41104?usp=email )
Change subject: [REST] Implement ErabList and ErabInfo ......................................................................
[REST] Implement ErabList and ErabInfo
Change-Id: Ia98498143fd0e38030429171e42a0c4c4887df64 Related: SYS#7066 --- M contrib/openapi.yaml M contrib/osmo-s1gw-cli.py M doc/osmo-s1gw-cli.md M priv/openapi.json M src/rest_server.erl 5 files changed, 229 insertions(+), 1 deletion(-)
Approvals: osmith: Looks good to me, but someone else must approve fixeria: Looks good to me, approved laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/contrib/openapi.yaml b/contrib/openapi.yaml index 0041274..adf3e58 100644 --- a/contrib/openapi.yaml +++ b/contrib/openapi.yaml @@ -108,6 +108,34 @@ '404': description: Unsuccessful outcome (eNB not found)
+ /erab-list: + get: + summary: Get E-RAB list for all eNBs + operationId: ErabList + responses: + '200': + description: A list of E-RABs + content: + application/json: + schema: + $ref: '#/components/schemas/ErabList' + + /erab/{ErabId}: + get: + summary: Get information about a specific E-RAB + operationId: ErabInfo + parameters: + - $ref: '#/components/parameters/ErabId' + responses: + '200': + description: Successful outcome (E-RAB info) + content: + application/json: + schema: + $ref: '#/components/schemas/ErabItem' + '404': + description: Unsuccessful outcome (E-RAB not found) + components: responses: OperationResult: @@ -146,6 +174,18 @@ description: eNB connection address/port example: enb-conn:192.168.1.1-34650
+ ErabId: + name: ErabId + in: path + description: E-RAB identifier (selector) + required: true + schema: + oneOf: + - type: string + pattern: '^pid:[0-9]+.[0-9]+.[0-9]+$' + description: Process ID + example: pid:0.33.1 + schemas: OperationResult: type: object diff --git a/contrib/osmo-s1gw-cli.py b/contrib/osmo-s1gw-cli.py index 5b749aa..99b62da 100755 --- a/contrib/osmo-s1gw-cli.py +++ b/contrib/osmo-s1gw-cli.py @@ -117,6 +117,16 @@ with self.send_get_req(f'enb/{enb_id}/erab-list') as f: return json.load(f)
+ def erab_list(self) -> RESTResponse: + ''' ErabList :: Get E-RAB list for all eNBs ''' + with self.send_get_req('erab-list') as f: + return json.load(f) + + def erab_info(self, pid: str) -> RESTResponse: + ''' ErabInfo :: Get information about a specific E-RAB ''' + with self.send_get_req(f'erab/pid:{pid}') as f: + return json.load(f) +
class OsmoS1GWCli(cmd2.Cmd): DESC = 'Interactive CLI for OsmoS1GW' @@ -124,6 +134,7 @@ CAT_METRICS = 'Metrics commands' CAT_PFCP = 'PFCP related commands' CAT_ENB = 'eNB related commands' + CAT_ERAB = 'E-RAB related commands'
def __init__(self, argv): super().__init__(allow_cli_args=False, include_py=True) @@ -319,6 +330,12 @@ self.poutput(tabulate.tabulate(map(func, items), headers='keys', tablefmt=self.tablefmt))
+ def erab_info_print(self, item: dict) -> None: + ''' Print E-RAB info in tabular form ''' + self.poutput(tabulate.tabulate(self.erab_list_item_full(item).items(), + headers=['Parameter', 'Value'], + tablefmt=self.tablefmt)) + enb_erab_list_parser = cmd2.Cmd2ArgumentParser() enb_erab_list_parser.add_argument('-f', '--full', action='store_true', @@ -333,6 +350,30 @@ data = self.iface.enb_erab_list(enb_id) self.erab_list_print(data, opts.full)
+ erab_list_parser = cmd2.Cmd2ArgumentParser() + erab_list_parser.add_argument('-f', '--full', + action='store_true', + help='Print full table (more columns)') + + @cmd2.with_argparser(erab_list_parser) + @cmd2.with_category(CAT_ERAB) + def do_erab_list(self, opts) -> None: + ''' Get E-RAB list for all eNBs ''' + data = self.iface.erab_list() + self.erab_list_print(data, opts.full) + + erab_info_parser = cmd2.Cmd2ArgumentParser() + erab_info_parser.add_argument('-P', '--pid', + type=str, required=True, + help='E-RAB process ID (example: 0.33.1)') + + @cmd2.with_argparser(erab_info_parser) + @cmd2.with_category(CAT_ERAB) + def do_erab_info(self, opts) -> None: + ''' Get information about a specific E-RAB ''' + data = self.iface.erab_info(opts.pid) + self.erab_info_print(data) +
ap = argparse.ArgumentParser(prog='osmo-s1gw-cli', description=OsmoS1GWCli.DESC)
diff --git a/doc/osmo-s1gw-cli.md b/doc/osmo-s1gw-cli.md index 6509563..b801b25 100644 --- a/doc/osmo-s1gw-cli.md +++ b/doc/osmo-s1gw-cli.md @@ -268,3 +268,54 @@ | <0.707.0> | 4242 | 0 | erab_setup | | <0.709.0> | 4242 | 2 | erab_setup | ``` + +### `erab_list` + +Get E-RAB list for all eNBs. + +``` +Usage: erab_list [-h] [-f] + +Get E-RAB list for all eNBs + +optional arguments: + -h, --help show this help message and exit + -f, --full Print full table (more columns) +``` + +The output format is the same as produced by the `enb_erab_list` command. + +### `erab_info` + +Get information about a specific E-RAB. + +``` +Usage: erab_info -P PID [-h] + +Get information about a specific E-RAB + +required arguments: + -P, --pid PID E-RAB process ID (example: 0.33.1) + +optional arguments: + -h, --help show this help message and exit + +``` + +Example: Obtaining E-RAB info using process ID. + +``` +OsmoS1GW# erab_info -P 0.714.0 +| Parameter | Value | +|----------------|----------------------| +| PID | <0.714.0> | +| MME-UE-S1AP-ID | 4242 | +| E-RAB-ID | 1 | +| State | erab_setup | +| SEID (local) | 0x0000000000000002 | +| SEID (remote) | 0x5454434e2d330001 | +| U2C F-TEID | 0x00010001@127.0.0.1 | +| C2U F-TEID | 0x01010001@127.0.1.1 | +| A2U F-TEID | 0x02020001@127.0.2.2 | +| U2A F-TEID | 0x00020001@127.0.0.2 | +``` diff --git a/priv/openapi.json b/priv/openapi.json index 07a11b8..bfe82a3 100644 --- a/priv/openapi.json +++ b/priv/openapi.json @@ -166,6 +166,50 @@ } } } + }, + "/erab-list": { + "get": { + "summary": "Get E-RAB list for all eNBs", + "operationId": "ErabList", + "responses": { + "200": { + "description": "A list of E-RABs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErabList" + } + } + } + } + } + } + }, + "/erab/{ErabId}": { + "get": { + "summary": "Get information about a specific E-RAB", + "operationId": "ErabInfo", + "parameters": [ + { + "$ref": "#/components/parameters/ErabId" + } + ], + "responses": { + "200": { + "description": "Successful outcome (E-RAB info)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErabItem" + } + } + } + }, + "404": { + "description": "Unsuccessful outcome (E-RAB not found)" + } + } + } } }, "components": { @@ -221,6 +265,22 @@ } ] } + }, + "ErabId": { + "name": "ErabId", + "in": "path", + "description": "E-RAB identifier (selector)", + "required": true, + "schema": { + "oneOf": [ + { + "type": "string", + "pattern": "^pid:[0-9]+\.[0-9]+\.[0-9]+$", + "description": "Process ID", + "example": "pid:0.33.1" + } + ] + } } }, "schemas": { diff --git a/src/rest_server.erl b/src/rest_server.erl index 2f805da..e1333c0 100644 --- a/src/rest_server.erl +++ b/src/rest_server.erl @@ -39,7 +39,9 @@ pfcp_heartbeat/1, enb_list/1, enb_info/1, - enb_erab_list/1 + enb_erab_list/1, + erab_list/1, + erab_info/1 ]).
-include_lib("kernel/include/logger.hrl"). @@ -120,6 +122,24 @@ end.
+%% ErabList :: Get E-RAB list for all eNBs +erab_list(#{}) -> + EnbList = enb_registry:fetch_enb_list(), + ErabList = lists:map(fun fetch_erab_list/1, EnbList), + {200, [], lists:flatten(ErabList)}. + + +%% ErabInfo :: Get information about a specific E-RAB +erab_info(#{path_parameters := PP}) -> + [{<< "ErabId" >>, << ID/bytes >>}] = PP, + case fetch_erab_info(ID) of + {ok, ErabInfo} -> + {200, [], ErabInfo}; + error -> + {404, [], undefined} + end. + + %% ------------------------------------------------------------------ %% private API %% ------------------------------------------------------------------ @@ -245,6 +265,22 @@ error.
+-spec fetch_erab_info(binary()) -> {ok, erab_fsm:erab_info()} | error. +fetch_erab_info(<< "pid:", Val/bytes >>) -> + Pid = parse_pid(Val), + %% guard against non-existent process IDs + %% TODO: check if the given Pid is actually an erab_fsm + try erab_list_item({pid, Pid}) of + ErabInfo -> {ok, ErabInfo} + catch + exit:{noproc, _} -> error + end; + +fetch_erab_info(ID) -> + ?LOG_ERROR("Unhandled E-RAB ID ~p", [ID]), + error. + + -spec fetch_erab_list(enb_registry:enb_info()) -> [map()]. fetch_erab_list(#{mme_conn_info := ConnInfo}) -> Pid = maps:get(handler, ConnInfo), %% s1ap_proxy process pid