diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb97422 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +go.work.sum diff --git a/backend/docs/docs.go b/backend/docs/docs.go index 09a782f..9a2e3c6 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -37,9 +37,595 @@ const docTemplate = `{ } } } + }, + "/auth/login": { + "post": { + "description": "Authenticate with login and password, returns a token and permissions", + "consumes": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Login", + "parameters": [ + { + "description": "Login credentials", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/token": { + "post": { + "description": "Creates a new user with permissions", + "consumes": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Create user", + "parameters": [ + { + "description": "User data", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "Deletes the current authenticated user", + "tags": [ + "auth" + ], + "summary": "Delete my account", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/tokens": { + "get": { + "description": "Returns list of all users with their permissions", + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "List users", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/tokens/:login": { + "delete": { + "description": "Deletes a user by their login", + "tags": [ + "auth" + ], + "summary": "Delete user", + "parameters": [ + { + "type": "string", + "description": "Login of the user to delete", + "name": "login", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/validate": { + "get": { + "description": "Check if the provided Bearer token is valid and return its permissions", + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Validate token", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/logs": { + "get": { + "description": "Searches logs with various filters", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Search logs", + "parameters": [ + { + "type": "string", + "description": "Log level (INFO, WARNING, ERROR, FATAL)", + "name": "level", + "in": "query" + }, + { + "type": "string", + "description": "Service name", + "name": "service", + "in": "query" + }, + { + "type": "string", + "description": "Agent name", + "name": "agent", + "in": "query" + }, + { + "type": "string", + "description": "Date from (RFC3339)", + "name": "date_from", + "in": "query" + }, + { + "type": "string", + "description": "Date to (RFC3339)", + "name": "date_to", + "in": "query" + }, + { + "type": "integer", + "default": 100, + "description": "Limit results", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Offset results", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry" + } + } + } + } + }, + "post": { + "description": "Inserts a single log entry into ClickHouse", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Insert log entry", + "parameters": [ + { + "description": "Log entry", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.InsertLogRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/logs/agents": { + "get": { + "description": "Returns list of all unique agent names in logs", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Get distinct agents", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/logs/batch": { + "post": { + "description": "Inserts multiple log entries into ClickHouse", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Insert log entries (batch)", + "parameters": [ + { + "description": "Log entries", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.InsertLogsRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/logs/levels": { + "get": { + "description": "Returns list of all unique log levels in logs", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Get distinct log levels", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/logs/services": { + "get": { + "description": "Returns list of all unique service names in logs", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Get distinct services", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } } }, "definitions": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest": { + "type": "object", + "required": [ + "login", + "password" + ], + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse": { + "type": "object", + "properties": { + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "permission_admin": { + "type": "boolean" + }, + "permission_manage_agent": { + "type": "boolean" + }, + "permission_view": { + "type": "boolean" + }, + "token": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate": { + "type": "object", + "required": [ + "last_name", + "login", + "name", + "password" + ], + "properties": { + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "permission_admin": { + "type": "boolean" + }, + "permission_manage_agent": { + "type": "boolean" + }, + "permission_view": { + "type": "boolean" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "permission_admin": { + "type": "boolean" + }, + "permission_manage_agent": { + "type": "boolean" + }, + "permission_view": { + "type": "boolean" + }, + "token": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry": { + "type": "object", + "properties": { + "agent": { + "type": "string" + }, + "level": { + "type": "string" + }, + "message": { + "type": "string" + }, + "service": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + } + }, "internal_handlers.AgentInfo": { "type": "object", "properties": { @@ -56,6 +642,46 @@ const docTemplate = `{ "type": "string" } } + }, + "internal_handlers.InsertLogRequest": { + "type": "object", + "required": [ + "agent", + "level", + "message", + "service" + ], + "properties": { + "agent": { + "type": "string" + }, + "level": { + "type": "string" + }, + "message": { + "type": "string" + }, + "service": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + } + }, + "internal_handlers.InsertLogsRequest": { + "type": "object", + "required": [ + "logs" + ], + "properties": { + "logs": { + "type": "array", + "items": { + "$ref": "#/definitions/internal_handlers.InsertLogRequest" + } + } + } } }, "securityDefinitions": { diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 7dd312c..922388b 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -26,9 +26,595 @@ } } } + }, + "/auth/login": { + "post": { + "description": "Authenticate with login and password, returns a token and permissions", + "consumes": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Login", + "parameters": [ + { + "description": "Login credentials", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/token": { + "post": { + "description": "Creates a new user with permissions", + "consumes": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Create user", + "parameters": [ + { + "description": "User data", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "Deletes the current authenticated user", + "tags": [ + "auth" + ], + "summary": "Delete my account", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/tokens": { + "get": { + "description": "Returns list of all users with their permissions", + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "List users", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/tokens/:login": { + "delete": { + "description": "Deletes a user by their login", + "tags": [ + "auth" + ], + "summary": "Delete user", + "parameters": [ + { + "type": "string", + "description": "Login of the user to delete", + "name": "login", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/validate": { + "get": { + "description": "Check if the provided Bearer token is valid and return its permissions", + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Validate token", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/logs": { + "get": { + "description": "Searches logs with various filters", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Search logs", + "parameters": [ + { + "type": "string", + "description": "Log level (INFO, WARNING, ERROR, FATAL)", + "name": "level", + "in": "query" + }, + { + "type": "string", + "description": "Service name", + "name": "service", + "in": "query" + }, + { + "type": "string", + "description": "Agent name", + "name": "agent", + "in": "query" + }, + { + "type": "string", + "description": "Date from (RFC3339)", + "name": "date_from", + "in": "query" + }, + { + "type": "string", + "description": "Date to (RFC3339)", + "name": "date_to", + "in": "query" + }, + { + "type": "integer", + "default": 100, + "description": "Limit results", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Offset results", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry" + } + } + } + } + }, + "post": { + "description": "Inserts a single log entry into ClickHouse", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Insert log entry", + "parameters": [ + { + "description": "Log entry", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.InsertLogRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/logs/agents": { + "get": { + "description": "Returns list of all unique agent names in logs", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Get distinct agents", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/logs/batch": { + "post": { + "description": "Inserts multiple log entries into ClickHouse", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Insert log entries (batch)", + "parameters": [ + { + "description": "Log entries", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.InsertLogsRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/logs/levels": { + "get": { + "description": "Returns list of all unique log levels in logs", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Get distinct log levels", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/logs/services": { + "get": { + "description": "Returns list of all unique service names in logs", + "produces": [ + "application/json" + ], + "tags": [ + "logs" + ], + "summary": "Get distinct services", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } } }, "definitions": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest": { + "type": "object", + "required": [ + "login", + "password" + ], + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse": { + "type": "object", + "properties": { + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "permission_admin": { + "type": "boolean" + }, + "permission_manage_agent": { + "type": "boolean" + }, + "permission_view": { + "type": "boolean" + }, + "token": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate": { + "type": "object", + "required": [ + "last_name", + "login", + "name", + "password" + ], + "properties": { + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "permission_admin": { + "type": "boolean" + }, + "permission_manage_agent": { + "type": "boolean" + }, + "permission_view": { + "type": "boolean" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "permission_admin": { + "type": "boolean" + }, + "permission_manage_agent": { + "type": "boolean" + }, + "permission_view": { + "type": "boolean" + }, + "token": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry": { + "type": "object", + "properties": { + "agent": { + "type": "string" + }, + "level": { + "type": "string" + }, + "message": { + "type": "string" + }, + "service": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + } + }, "internal_handlers.AgentInfo": { "type": "object", "properties": { @@ -45,6 +631,46 @@ "type": "string" } } + }, + "internal_handlers.InsertLogRequest": { + "type": "object", + "required": [ + "agent", + "level", + "message", + "service" + ], + "properties": { + "agent": { + "type": "string" + }, + "level": { + "type": "string" + }, + "message": { + "type": "string" + }, + "service": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + } + }, + "internal_handlers.InsertLogsRequest": { + "type": "object", + "required": [ + "logs" + ], + "properties": { + "logs": { + "type": "array", + "items": { + "$ref": "#/definitions/internal_handlers.InsertLogRequest" + } + } + } } }, "securityDefinitions": { diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 1c3570d..1c8fa86 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -1,4 +1,85 @@ definitions: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest: + properties: + login: + type: string + password: + type: string + required: + - login + - password + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse: + properties: + last_name: + type: string + login: + type: string + name: + type: string + permission_admin: + type: boolean + permission_manage_agent: + type: boolean + permission_view: + type: boolean + token: + type: string + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate: + properties: + last_name: + type: string + login: + type: string + name: + type: string + password: + type: string + permission_admin: + type: boolean + permission_manage_agent: + type: boolean + permission_view: + type: boolean + required: + - last_name + - login + - name + - password + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens: + properties: + id: + type: integer + last_name: + type: string + login: + type: string + name: + type: string + permission_admin: + type: boolean + permission_manage_agent: + type: boolean + permission_view: + type: boolean + token: + type: string + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry: + properties: + agent: + type: string + level: + type: string + message: + type: string + service: + type: string + timestamp: + type: string + type: object internal_handlers.AgentInfo: properties: label: @@ -10,6 +91,33 @@ definitions: token: type: string type: object + internal_handlers.InsertLogRequest: + properties: + agent: + type: string + level: + type: string + message: + type: string + service: + type: string + timestamp: + type: string + required: + - agent + - level + - message + - service + type: object + internal_handlers.InsertLogsRequest: + properties: + logs: + items: + $ref: '#/definitions/internal_handlers.InsertLogRequest' + type: array + required: + - logs + type: object info: contact: {} paths: @@ -28,6 +136,311 @@ paths: summary: Get connected agents tags: - agents + /auth/login: + post: + consumes: + - application/json + description: Authenticate with login and password, returns a token and permissions + parameters: + - description: Login credentials + in: body + name: request + required: true + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse' + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "401": + description: Unauthorized + schema: + additionalProperties: + type: string + type: object + summary: Login + tags: + - auth + /auth/token: + delete: + description: Deletes the current authenticated user + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "401": + description: Unauthorized + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: Delete my account + tags: + - auth + post: + consumes: + - application/json + description: Creates a new user with permissions + parameters: + - description: User data + in: body + name: request + required: true + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate' + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "401": + description: Unauthorized + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: Create user + tags: + - auth + /auth/tokens: + get: + description: Returns list of all users with their permissions + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens' + type: array + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: List users + tags: + - auth + /auth/tokens/:login: + delete: + description: Deletes a user by their login + parameters: + - description: Login of the user to delete + in: path + name: login + required: true + type: string + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: Delete user + tags: + - auth + /auth/validate: + get: + description: Check if the provided Bearer token is valid and return its permissions + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens' + "401": + description: Unauthorized + schema: + additionalProperties: + type: string + type: object + summary: Validate token + tags: + - auth + /logs: + get: + description: Searches logs with various filters + parameters: + - description: Log level (INFO, WARNING, ERROR, FATAL) + in: query + name: level + type: string + - description: Service name + in: query + name: service + type: string + - description: Agent name + in: query + name: agent + type: string + - description: Date from (RFC3339) + in: query + name: date_from + type: string + - description: Date to (RFC3339) + in: query + name: date_to + type: string + - default: 100 + description: Limit results + in: query + name: limit + type: integer + - default: 0 + description: Offset results + in: query + name: offset + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry' + type: array + summary: Search logs + tags: + - logs + post: + consumes: + - application/json + description: Inserts a single log entry into ClickHouse + parameters: + - description: Log entry + in: body + name: body + required: true + schema: + $ref: '#/definitions/internal_handlers.InsertLogRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + additionalProperties: + type: string + type: object + summary: Insert log entry + tags: + - logs + /logs/agents: + get: + description: Returns list of all unique agent names in logs + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + type: string + type: array + summary: Get distinct agents + tags: + - logs + /logs/batch: + post: + consumes: + - application/json + description: Inserts multiple log entries into ClickHouse + parameters: + - description: Log entries + in: body + name: body + required: true + schema: + $ref: '#/definitions/internal_handlers.InsertLogsRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + additionalProperties: + type: string + type: object + summary: Insert log entries (batch) + tags: + - logs + /logs/levels: + get: + description: Returns list of all unique log levels in logs + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + type: string + type: array + summary: Get distinct log levels + tags: + - logs + /logs/services: + get: + description: Returns list of all unique service names in logs + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + type: string + type: array + summary: Get distinct services + tags: + - logs securityDefinitions: Bearer: description: Type "Bearer" followed by a space and the JWT token. diff --git a/infra/agent/config.yml b/infra/agent/config.yml new file mode 100644 index 0000000..333d79d --- /dev/null +++ b/infra/agent/config.yml @@ -0,0 +1,5 @@ +backend_url: http://backend:8080 +label: test-agent-1 +services: + - service1 + - service2 diff --git a/infra/backend/config.yml b/infra/backend/config.yml new file mode 100644 index 0000000..d837afc --- /dev/null +++ b/infra/backend/config.yml @@ -0,0 +1,5 @@ +database: + token_db: /var/lib/hellreign/tokens.db + clickhouse_host: clickhouse:9000 + clickhouse_user: default + clickhouse_password: testpassword diff --git a/infra/clickhouse/init/01_create_logs_table.sh b/infra/clickhouse/init/01_create_logs_table.sh new file mode 100644 index 0000000..b6a900a --- /dev/null +++ b/infra/clickhouse/init/01_create_logs_table.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +clickhouse-client --query "CREATE DATABASE IF NOT EXISTS hellreign;" + +clickhouse-client --query " +CREATE TABLE IF NOT EXISTS hellreign.logs ( + timestamp DateTime64(3) DEFAULT now(), + level String, + service String, + message String, + host String, + trace_id String +) ENGINE = MergeTree() +ORDER BY (timestamp, service, level); +" diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml index 1ba2a8a..f04ec9b 100644 --- a/infra/docker-compose.yml +++ b/infra/docker-compose.yml @@ -1,3 +1,70 @@ services: + clickhouse: + image: clickhouse/clickhouse-server:24.8 + container_name: hellreign-clickhouse + environment: + CLICKHOUSE_DB: hellreign + CLICKHOUSE_USER: default + CLICKHOUSE_PASSWORD: testpassword + CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1 + ports: + - "8123:8123" + - "9000:9000" + volumes: + - clickhouse_data:/var/lib/clickhouse + - ./clickhouse/init:/docker-entrypoint-initdb.d + networks: + - hellreign + backend: - + build: + context: ../backend + dockerfile: dockerfile + container_name: hellreign-backend + environment: + CONFIG_FILE: /etc/hellreign/config.yml + ports: + - "8080:8080" + volumes: + - ./backend/config.yml:/etc/hellreign/config.yml:ro + - backend_data:/var/lib/hellreign + depends_on: + - clickhouse + networks: + - hellreign + + frontend: + build: + context: ../frontend + dockerfile: dockerfile + container_name: hellreign-frontend + ports: + - "3000:80" + depends_on: + - backend + networks: + - hellreign + + agent: + build: + context: ../agent + dockerfile: dockerfile + container_name: hellreign-agent + environment: + CONFIG_FILE: /etc/hellreign-agent/config.yml + volumes: + - ./agent/config.yml:/etc/hellreign-agent/config.yml:ro + depends_on: + - backend + networks: + - hellreign + +volumes: + clickhouse_data: + driver: local + backend_data: + driver: local + +networks: + hellreign: + driver: bridge