Add missing, fix wrong API endpoint descriptions

This commit is contained in:
Ingo Oppermann 2025-12-01 15:13:46 +01:00
parent db9154608e
commit 9af53917f4
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
7 changed files with 666 additions and 195 deletions

View File

@ -109,6 +109,76 @@ const docTemplate = `{
}
}
},
"/api/login": {
"post": {
"description": "Create a JWT from username/password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Create a JWT",
"operationId": "login",
"parameters": [
{
"description": "User definition",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.Login"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.JWT"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/login/refresh": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Refresh a JWT",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Refresh a JWT",
"operationId": "refresh",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.JWTRefresh"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/swagger": {
"get": {
"description": "Swagger UI for this API",
@ -488,7 +558,7 @@ const docTemplate = `{
"ApiKeyAuth": []
}
],
"description": "Stream of events of whats happening on each node in the cluster",
"description": "Stream of log events of whats happening on each node in the cluster",
"consumes": [
"application/json"
],
@ -499,7 +569,7 @@ const docTemplate = `{
"tags": [
"v16.?.?"
],
"summary": "Stream of events",
"summary": "Stream of log events",
"operationId": "cluster-3-events",
"parameters": [
{
@ -515,7 +585,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.Event"
"$ref": "#/definitions/api.LogEvent"
}
}
}
@ -2500,7 +2570,7 @@ const docTemplate = `{
"ApiKeyAuth": []
}
],
"description": "Stream of event of whats happening in the core",
"description": "Stream of log event of whats happening in the core",
"consumes": [
"application/json"
],
@ -2511,8 +2581,8 @@ const docTemplate = `{
"tags": [
"v16.?.?"
],
"summary": "Stream of events",
"operationId": "events",
"summary": "Stream of log events",
"operationId": "events-3-media",
"parameters": [
{
"description": "Event filters",
@ -2527,7 +2597,44 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.Event"
"$ref": "#/definitions/api.MediaEvent"
}
}
}
}
},
"/api/v3/events/media/{type}": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Stream of media event of whats happening in the core",
"consumes": [
"application/json"
],
"produces": [
"application/x-json-stream"
],
"tags": [
"v16.?.?"
],
"summary": "Stream of media events",
"operationId": "events-3-log",
"parameters": [
{
"type": "string",
"description": "glob pattern for media names",
"name": "glob",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.LogEvent"
}
}
}
@ -4986,8 +5093,7 @@ const docTemplate = `{
],
"description": "List all currently publishing RTMP streams.",
"produces": [
"application/json",
"application/x-json-stream"
"application/json"
],
"tags": [
"v16.7.2"
@ -5207,8 +5313,7 @@ const docTemplate = `{
],
"description": "List all currently publishing SRT streams. This endpoint is EXPERIMENTAL and may change in future.",
"produces": [
"application/json",
"application/x-json-stream"
"application/json"
],
"tags": [
"v16.9.0"
@ -6670,69 +6775,13 @@ const docTemplate = `{
}
}
},
"api.Event": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "integer"
},
"message": {
"type": "string"
},
"ts": {
"type": "integer",
"format": "int64"
}
}
},
"api.EventFilter": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"api.EventFilters": {
"type": "object",
"properties": {
"filters": {
"type": "array",
"items": {
"$ref": "#/definitions/api.EventFilter"
"$ref": "#/definitions/api.LogEventFilter"
}
}
}
@ -7042,10 +7091,120 @@ const docTemplate = `{
}
}
},
"api.LogEvent": {
"api.JWT": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"refresh_token": {
"type": "string"
}
}
},
"api.JWTRefresh": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
}
}
},
"api.LogEntries": {
"type": "object",
"additionalProperties": true
},
"api.LogEvent": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "integer"
},
"message": {
"type": "string"
},
"ts": {
"type": "integer",
"format": "int64"
}
}
},
"api.LogEventFilter": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"api.Login": {
"type": "object",
"required": [
"password",
"username"
],
"properties": {
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"api.MediaEvent": {
"type": "object",
"properties": {
"action": {
"type": "string"
},
"name": {
"type": "string"
},
"names": {
"type": "array",
"items": {
"type": "string"
}
},
"ts": {
"type": "integer"
}
}
},
"api.MetricsDescription": {
"type": "object",
"properties": {

View File

@ -102,6 +102,76 @@
}
}
},
"/api/login": {
"post": {
"description": "Create a JWT from username/password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Create a JWT",
"operationId": "login",
"parameters": [
{
"description": "User definition",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.Login"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.JWT"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/login/refresh": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Refresh a JWT",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Refresh a JWT",
"operationId": "refresh",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.JWTRefresh"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/api/swagger": {
"get": {
"description": "Swagger UI for this API",
@ -481,7 +551,7 @@
"ApiKeyAuth": []
}
],
"description": "Stream of events of whats happening on each node in the cluster",
"description": "Stream of log events of whats happening on each node in the cluster",
"consumes": [
"application/json"
],
@ -492,7 +562,7 @@
"tags": [
"v16.?.?"
],
"summary": "Stream of events",
"summary": "Stream of log events",
"operationId": "cluster-3-events",
"parameters": [
{
@ -508,7 +578,7 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.Event"
"$ref": "#/definitions/api.LogEvent"
}
}
}
@ -2493,7 +2563,7 @@
"ApiKeyAuth": []
}
],
"description": "Stream of event of whats happening in the core",
"description": "Stream of log event of whats happening in the core",
"consumes": [
"application/json"
],
@ -2504,8 +2574,8 @@
"tags": [
"v16.?.?"
],
"summary": "Stream of events",
"operationId": "events",
"summary": "Stream of log events",
"operationId": "events-3-media",
"parameters": [
{
"description": "Event filters",
@ -2520,7 +2590,44 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.Event"
"$ref": "#/definitions/api.MediaEvent"
}
}
}
}
},
"/api/v3/events/media/{type}": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Stream of media event of whats happening in the core",
"consumes": [
"application/json"
],
"produces": [
"application/x-json-stream"
],
"tags": [
"v16.?.?"
],
"summary": "Stream of media events",
"operationId": "events-3-log",
"parameters": [
{
"type": "string",
"description": "glob pattern for media names",
"name": "glob",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.LogEvent"
}
}
}
@ -4979,8 +5086,7 @@
],
"description": "List all currently publishing RTMP streams.",
"produces": [
"application/json",
"application/x-json-stream"
"application/json"
],
"tags": [
"v16.7.2"
@ -5200,8 +5306,7 @@
],
"description": "List all currently publishing SRT streams. This endpoint is EXPERIMENTAL and may change in future.",
"produces": [
"application/json",
"application/x-json-stream"
"application/json"
],
"tags": [
"v16.9.0"
@ -6663,69 +6768,13 @@
}
}
},
"api.Event": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "integer"
},
"message": {
"type": "string"
},
"ts": {
"type": "integer",
"format": "int64"
}
}
},
"api.EventFilter": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"api.EventFilters": {
"type": "object",
"properties": {
"filters": {
"type": "array",
"items": {
"$ref": "#/definitions/api.EventFilter"
"$ref": "#/definitions/api.LogEventFilter"
}
}
}
@ -7035,10 +7084,120 @@
}
}
},
"api.LogEvent": {
"api.JWT": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"refresh_token": {
"type": "string"
}
}
},
"api.JWTRefresh": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
}
}
},
"api.LogEntries": {
"type": "object",
"additionalProperties": true
},
"api.LogEvent": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "integer"
},
"message": {
"type": "string"
},
"ts": {
"type": "integer",
"format": "int64"
}
}
},
"api.LogEventFilter": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"core_id": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"event": {
"type": "string"
},
"level": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"api.Login": {
"type": "object",
"required": [
"password",
"username"
],
"properties": {
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"api.MediaEvent": {
"type": "object",
"properties": {
"action": {
"type": "string"
},
"name": {
"type": "string"
},
"names": {
"type": "array",
"items": {
"type": "string"
}
},
"ts": {
"type": "integer"
}
}
},
"api.MetricsDescription": {
"type": "object",
"properties": {

View File

@ -911,48 +911,11 @@ definitions:
message:
type: string
type: object
api.Event:
properties:
caller:
type: string
core_id:
type: string
data:
additionalProperties:
type: string
type: object
event:
type: string
level:
type: integer
message:
type: string
ts:
format: int64
type: integer
type: object
api.EventFilter:
properties:
caller:
type: string
core_id:
type: string
data:
additionalProperties:
type: string
type: object
event:
type: string
level:
type: string
message:
type: string
type: object
api.EventFilters:
properties:
filters:
items:
$ref: '#/definitions/api.EventFilter'
$ref: '#/definitions/api.LogEventFilter'
type: array
type: object
api.FileInfo:
@ -1157,9 +1120,81 @@ definitions:
type: string
type: array
type: object
api.LogEvent:
api.JWT:
properties:
access_token:
type: string
refresh_token:
type: string
type: object
api.JWTRefresh:
properties:
access_token:
type: string
type: object
api.LogEntries:
additionalProperties: true
type: object
api.LogEvent:
properties:
caller:
type: string
core_id:
type: string
data:
additionalProperties:
type: string
type: object
event:
type: string
level:
type: integer
message:
type: string
ts:
format: int64
type: integer
type: object
api.LogEventFilter:
properties:
caller:
type: string
core_id:
type: string
data:
additionalProperties:
type: string
type: object
event:
type: string
level:
type: string
message:
type: string
type: object
api.Login:
properties:
password:
type: string
username:
type: string
required:
- password
- username
type: object
api.MediaEvent:
properties:
action:
type: string
name:
type: string
names:
items:
type: string
type: array
ts:
type: integer
type: object
api.MetricsDescription:
properties:
description:
@ -2973,6 +3008,51 @@ paths:
security:
- ApiKeyAuth: []
summary: Query the GraphAPI
/api/login:
post:
consumes:
- application/json
description: Create a JWT from username/password
operationId: login
parameters:
- description: User definition
in: body
name: user
required: true
schema:
$ref: '#/definitions/api.Login'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/api.JWT'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
summary: Create a JWT
/api/login/refresh:
get:
consumes:
- application/json
description: Refresh a JWT
operationId: refresh
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/api.JWTRefresh'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
security:
- ApiKeyAuth: []
summary: Refresh a JWT
/api/swagger:
get:
description: Swagger UI for this API
@ -3209,7 +3289,7 @@ paths:
post:
consumes:
- application/json
description: Stream of events of whats happening on each node in the cluster
description: Stream of log events of whats happening on each node in the cluster
operationId: cluster-3-events
parameters:
- description: Event filters
@ -3224,10 +3304,10 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/api.Event'
$ref: '#/definitions/api.LogEvent'
security:
- ApiKeyAuth: []
summary: Stream of events
summary: Stream of log events
tags:
- v16.?.?
/api/v3/cluster/fs/{storage}:
@ -4531,8 +4611,8 @@ paths:
post:
consumes:
- application/json
description: Stream of event of whats happening in the core
operationId: events
description: Stream of log event of whats happening in the core
operationId: events-3-media
parameters:
- description: Event filters
in: body
@ -4546,10 +4626,33 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/api.Event'
$ref: '#/definitions/api.MediaEvent'
security:
- ApiKeyAuth: []
summary: Stream of events
summary: Stream of log events
tags:
- v16.?.?
/api/v3/events/media/{type}:
post:
consumes:
- application/json
description: Stream of media event of whats happening in the core
operationId: events-3-log
parameters:
- description: glob pattern for media names
in: query
name: glob
type: string
produces:
- application/x-json-stream
responses:
"200":
description: OK
schema:
$ref: '#/definitions/api.LogEvent'
security:
- ApiKeyAuth: []
summary: Stream of media events
tags:
- v16.?.?
/api/v3/fs:
@ -6177,7 +6280,6 @@ paths:
operationId: rtmp-3-list-channels
produces:
- application/json
- application/x-json-stream
responses:
"200":
description: OK
@ -6318,7 +6420,6 @@ paths:
operationId: srt-3-list-channels
produces:
- application/json
- application/x-json-stream
responses:
"200":
description: OK

View File

@ -13,16 +13,16 @@ import (
"github.com/labstack/echo/v4"
)
// Events returns a stream of event
// @Summary Stream of events
// @Description Stream of events of whats happening on each node in the cluster
// Events returns a stream of log event
// @Summary Stream of log events
// @Description Stream of log events of whats happening on each node in the cluster
// @ID cluster-3-events
// @Tags v16.?.?
// @Accept json
// @Produce text/event-stream
// @Produce json-stream
// @Param filters body api.EventFilters false "Event filters"
// @Success 200 {object} api.Event
// @Success 200 {object} api.LogEvent
// @Security ApiKeyAuth
// @Router /api/v3/cluster/events [post]
func (h *ClusterHandler) Events(c echo.Context) error {

View File

@ -46,13 +46,13 @@ func (h *EventsHandler) AddMediaSource(name string, source event.MediaSource) {
// LogEvents returns a stream of event
// @Summary Stream of log events
// @Description Stream of log event of whats happening in the core
// @ID events
// @ID events-3-media
// @Tags v16.?.?
// @Accept json
// @Produce text/event-stream
// @Produce json-stream
// @Param filters body api.EventFilters false "Event filters"
// @Success 200 {object} api.Event
// @Success 200 {object} api.MediaEvent
// @Security ApiKeyAuth
// @Router /api/v3/events [post]
func (h *EventsHandler) LogEvents(c echo.Context) error {
@ -177,12 +177,12 @@ func (h *EventsHandler) LogEvents(c echo.Context) error {
// LogEvents returns a stream of media event
// @Summary Stream of media events
// @Description Stream of media event of whats happening in the core
// @ID events
// @ID events-3-log
// @Tags v16.?.?
// @Accept json
// @Param glob query string false "glob pattern for media names"
// @Produce json-stream
// @Success 200 {object} api.Event
// @Success 200 {object} api.LogEvent
// @Security ApiKeyAuth
// @Router /api/v3/events/media/{type} [post]
func (h *EventsHandler) MediaEvents(c echo.Context) error {

View File

@ -19,6 +19,16 @@ func NewJWT(iam iam.IAM) *JWTHandler {
}
}
// Login Creates a JWT from username/password
// @Summary Create a JWT
// @Description Create a JWT from username/password
// @ID login
// @Accept json
// @Produce json
// @Param user body api.Login true "User definition"
// @Success 200 {object} api.JWT
// @Failure 403 {object} api.Error
// @Router /api/login [post]
func (j *JWTHandler) Login(c echo.Context) error {
subject, ok := c.Get("user").(string)
if !ok {
@ -36,6 +46,16 @@ func (j *JWTHandler) Login(c echo.Context) error {
})
}
// Refresh Refreshes a JWT from refresh JWT
// @Summary Refresh a JWT
// @Description Refresh a JWT
// @ID refresh
// @Accept json
// @Produce json
// @Success 200 {object} api.JWTRefresh
// @Failure 403 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/login/refresh [get]
func (j *JWTHandler) Refresh(c echo.Context) error {
subject, ok := c.Get("user").(string)
if !ok {

View File

@ -6,7 +6,9 @@ import (
"reflect"
"runtime"
"runtime/debug"
"slices"
"strings"
"sync"
"time"
"github.com/datarhei/core/v16/encoding/json"
@ -15,6 +17,31 @@ import (
// LogLevel represents a log level
type Level uint
var components = []string{}
var lock = sync.Mutex{}
func registerComponent(component string) {
if len(component) == 0 {
return
}
lock.Lock()
defer lock.Unlock()
if slices.Contains(components, component) {
return
}
components = append(components, component)
}
func ListComponents() []string {
lock.Lock()
defer lock.Unlock()
return slices.Clone(components)
}
const (
Lsilent Level = 0
Lerror Level = 1
@ -108,6 +135,8 @@ type logger struct {
// New returns an implementation of the Logger interface.
func New(component string) Logger {
registerComponent(component)
l := &logger{
component: component,
}
@ -156,6 +185,8 @@ func (l *logger) WithComponent(component string) Logger {
clone := l.clone()
clone.component = component
registerComponent(component)
return clone
}
@ -219,9 +250,10 @@ func (e *Event) WithOutput(w Writer) Logger {
func (e *Event) WithComponent(component string) Logger {
clone := e.clone()
clone.Component = component
registerComponent(component)
return clone
}