From 4f5d3647e05d17b5fe9a33807d4e443c58e8e542 Mon Sep 17 00:00:00 2001 From: sonya-spasova Date: Thu, 6 Nov 2025 10:59:42 +0200 Subject: [PATCH 1/6] RED-174158: Automate cluster API docs --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c16b7395c..69dc3a6a28 100644 --- a/README.md +++ b/README.md @@ -199,4 +199,6 @@ nil pointer evaluating page.Page.Params ``` This happened for us when Hugo executed the `bannerText` logic, which inspected all parent pages by checking if they have a banner text set. The problem was that one of the parent folders was missing an `_index.md` file, which meant the folder couldn't be identified as a page. The solution was to add an `_index.md` file to the folder that didn't have it yet. - \ No newline at end of file + + +<> \ No newline at end of file From 6488e80db9a1bae0e906584fa14efaa63745fa30 Mon Sep 17 00:00:00 2001 From: sonya-spasova Date: Thu, 20 Nov 2025 10:22:05 +0200 Subject: [PATCH 2/6] RED-174158: Add Redis Cluster API in docs --- content/operate/rs/api/api-reference.md | 6 + .../operate/rs/api/api-reference/openapi.json | 2083 +++++++++++++++++ 2 files changed, 2089 insertions(+) create mode 100644 content/operate/rs/api/api-reference.md create mode 100644 content/operate/rs/api/api-reference/openapi.json diff --git a/content/operate/rs/api/api-reference.md b/content/operate/rs/api/api-reference.md new file mode 100644 index 0000000000..6e15ca75ac --- /dev/null +++ b/content/operate/rs/api/api-reference.md @@ -0,0 +1,6 @@ +--- +Title: Redis Enterprise API +linkTitle: API reference +layout: apireference +type: page +--- diff --git a/content/operate/rs/api/api-reference/openapi.json b/content/operate/rs/api/api-reference/openapi.json new file mode 100644 index 0000000000..1d1065dbf9 --- /dev/null +++ b/content/operate/rs/api/api-reference/openapi.json @@ -0,0 +1,2083 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Cluster API", + "description": "The next-generation REST API for managing a Redis Enterprise Cluster" + }, + "servers": [ + { + "url": "http://localhost:3346" + } + ], + "paths": { + "/v4/auth/authorize": { + "get": { + "summary": "Authorized a request and returns a token", + "description": "Authorized a request and returns a token", + "operationId": "authorize", + "tags": [ + "Auth" + ], + "parameters": [ + { + "name": "ttl", + "in": "query", + "required": false, + "schema": { + "type": "integer" + }, + "description": "Time-to-live (TTL) of the token in seconds" + } + ], + "responses": { + "200": { + "description": "Token response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JWT" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/v4/cluster/health": { + "get": { + "summary": "Get cluster health report.", + "description": "Cluster health report.", + "operationId": "cluster_health_report", + "tags": [ + "Cluster" + ], + "parameters": [ + { + "name": "issues_only", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + }, + "description": "indicate to return only resources with unhealthy status" + } + ], + "responses": { + "200": { + "description": "Cluster report is ready see detailed information.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClusterHealthReport" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + } + }, + "/v4/bdb/{db_id}/health": { + "get": { + "summary": "Get database health report.", + "description": "Database health check indication.", + "operationId": "database_health_report", + "tags": [ + "Database" + ], + "security": [ + { + "Auth": [ + "view_bdb_info" + ] + } + ], + "parameters": [ + { + "name": "db_id", + "in": "path", + "description": "database ID", + "required": true, + "schema": { + "type": "string", + "maxLength": 3 + } + }, + { + "name": "issues_only", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + }, + "description": "indicate to return only resources with unhealthy status" + } + ], + "responses": { + "200": { + "description": "Database report is ready see detailed information.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseHealthReport" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + } + }, + "/v4/feature-flags/flags/definition": { + "get": { + "summary": "Get feature flags list.", + "description": "List of available feature flags.", + "operationId": "get_feature_flags", + "tags": [ + "FeatureFlags" + ], + "responses": { + "200": { + "description": "List of feature flags.", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/FeatureFlagDefinitionResponse" + } + } + } + } + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + } + }, + "/v4/feature-flags/flags/definition/{flag_name}": { + "get": { + "summary": "Get single feature flag.", + "description": "Get single feature flag by unique name.", + "operationId": "get_feature_flag", + "tags": [ + "FeatureFlags" + ], + "parameters": [ + { + "name": "flag_name", + "in": "path", + "description": "The feature flag name", + "required": true, + "schema": { + "type": "string", + "x-go-type": "string" + }, + "example": "test-flag" + } + ], + "responses": { + "200": { + "description": "Feature flag information.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeatureFlagDefinitionResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + }, + "put": { + "summary": "Update feature flag.", + "description": "Update feature flag by unique name.", + "operationId": "update_feature_flag", + "tags": [ + "FeatureFlags" + ], + "parameters": [ + { + "name": "flag_name", + "in": "path", + "description": "The feature flag name", + "required": true, + "schema": { + "type": "string", + "x-go-type": "string" + }, + "example": "test-flag" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "anyOf": [ + { + "required": [ + "defaultVariant" + ] + }, + { + "required": [ + "targeting" + ] + } + ], + "properties": { + "defaultVariant": { + "type": "string", + "description": "The name of the variant to use as the default when no targeting rules match." + }, + "targeting": { + "type": "object", + "description": "Optional targeting rules that determine which variant to return based on context. Keys are strings, values can be any type.", + "additionalProperties": true + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Feature flag updated.", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + } + }, + "/v4/feature-flags/flags/evaluation/{flag_name}": { + "post": { + "summary": "Evaluate feature flag by context.", + "description": "Evaluate feature flag by context.", + "operationId": "evaluate_feature_flag", + "tags": [ + "FeatureFlags" + ], + "parameters": [ + { + "name": "flag_name", + "in": "path", + "description": "The feature flag name", + "required": true, + "schema": { + "type": "string" + }, + "example": "test-flag" + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "context": { + "type": "object", + "description": "Optional context object containing key-value pairs for targeting evaluation.", + "additionalProperties": true + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Feature flag evaluation result.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeatureFlagEvaluationResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + } + }, + "/v4/feature-flags/profiles/current": { + "put": { + "summary": "Update current profile.", + "description": "Update current profile by name.", + "operationId": "update_current_profile", + "tags": [ + "FeatureFlags" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "profile" + ], + "properties": { + "profile": { + "type": "string", + "minLength": 1, + "maxLength": 50, + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "The name of the profile, that will be used to update the current profile." + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Feature flags updating current profile.", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "503": { + "$ref": "#/components/responses/ServiceUnavailable" + } + } + } + }, + "/v1/migrations/{uid}": { + "get": { + "x-stability-level": "stable", + "summary": "Get migration status of a bdb in the cluster", + "description": "Migration status of a bdb in the cluster", + "operationId": "get_migration", + "tags": [ + "Migrations" + ], + "security": [ + { + "Auth": [ + "view_bdb_info" + ] + } + ], + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "The migration unique ID", + "required": true, + "schema": { + "type": "integer", + "x-go-type": "json.Number" + }, + "example": 1 + } + ], + "responses": { + "200": { + "description": "migration information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MigrationResponse" + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/v1/users/role": { + "get": { + "summary": "Get the management role of the authenticating user.", + "description": "Get the management role of the authenticating user.", + "operationId": "get_user_role", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [] + } + ], + "responses": { + "200": { + "description": "User role information", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "role": { + "$ref": "#/components/schemas/UserRole" + } + } + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + } + } + } + }, + "/v1/users/{uid}": { + "get": { + "summary": "Get a single Redis Enterprise Cluster user", + "description": "Get a single user by unique ID", + "operationId": "get_user", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [ + "view_user_info" + ] + } + ], + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "The user unique ID", + "required": true, + "schema": { + "type": "integer", + "x-go-type": "json.Number" + }, + "example": 1 + } + ], + "responses": { + "200": { + "description": "User information", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "delete": { + "summary": "Delete a Redis Enterprise Cluster user", + "description": "Delete a user by unique ID", + "operationId": "delete_user", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [ + "delete_user" + ] + } + ], + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "The user unique ID", + "required": true, + "schema": { + "type": "integer", + "x-go-type": "json.Number" + }, + "example": 1 + } + ], + "responses": { + "200": { + "description": "User deleted successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "action_uid": { + "type": "string", + "description": "Action uid for tracking progress" + } + }, + "example": { + "action_uid": "12345-abcde-67890" + } + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "406": { + "$ref": "#/components/responses/NotAcceptable" + } + } + }, + "put": { + "summary": "Update a Redis Enterprise Cluster user", + "description": "Update a user configuration by unique ID", + "operationId": "update_user", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [ + "update_user" + ] + } + ], + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "The user unique ID", + "required": true, + "schema": { + "type": "integer", + "x-go-type": "json.Number" + }, + "example": 1 + }, + { + "name": "dry_run", + "in": "query", + "description": "Validate the request without persisting changes", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "description": "User update data", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRequest" + }, + "example": { + "name": "Jane Poe", + "email_alerts": false + } + } + } + }, + "responses": { + "200": { + "description": "User updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "406": { + "$ref": "#/components/responses/NotAcceptable" + } + } + } + }, + "/v1/users": { + "get": { + "summary": "Get all Redis Enterprise Cluster users", + "description": "Get all Redis Enterprise Cluster users in the cluster", + "operationId": "get_users", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [ + "view_all_users_info" + ] + } + ], + "responses": { + "200": { + "description": "List of users", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + } + } + }, + "post": { + "summary": "Create a new Redis Enterprise Cluster user", + "description": "Create a new user with the provided configuration", + "operationId": "create_user", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [ + "create_new_user" + ] + } + ], + "parameters": [ + { + "name": "dry_run", + "in": "query", + "description": "Validate the request without persisting changes", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "description": "User creation data", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRequest" + } + } + } + }, + "responses": { + "200": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "409": { + "description": "User with the same email or name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/users/password": { + "put": { + "summary": "Reset user password", + "description": "Reset the password list of a user to include a single new password", + "operationId": "reset_user_password", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [] + } + ], + "requestBody": { + "description": "Password reset data", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The username of the affected user. If missing, defaults to authenticated user" + }, + "new_password": { + "type": "string", + "description": "The new password" + }, + "password_hash_method": { + "$ref": "#/components/schemas/PasswordHashMethod" + } + }, + "required": [ + "new_password" + ] + }, + "example": { + "username": "john.doe", + "new_password": "new-secure-password" + } + } + } + }, + "responses": { + "200": { + "description": "Password reset successfully" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "post": { + "summary": "Add user password", + "description": "Add a new password to a user's passwords list", + "operationId": "add_user_password", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [] + } + ], + "requestBody": { + "description": "Password addition data", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The username of the affected user. If missing, defaults to authenticated user" + }, + "new_password": { + "type": "string", + "description": "A password to add" + }, + "password_hash_method": { + "$ref": "#/components/schemas/PasswordHashMethod" + } + }, + "required": [ + "new_password" + ] + }, + "example": { + "username": "john.doe", + "new_password": "additional-password" + } + } + } + }, + "responses": { + "200": { + "description": "Password added successfully" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "delete": { + "summary": "Delete user password", + "description": "Delete a password from the list of a user's passwords", + "operationId": "delete_user_password", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [] + } + ], + "requestBody": { + "description": "Password deletion data", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The username of the affected user. If missing, defaults to authenticated user" + }, + "old_password": { + "type": "string", + "description": "An existing password to delete" + } + }, + "required": [ + "old_password" + ] + }, + "example": { + "username": "john.doe", + "old_password": "password-to-remove" + } + } + } + }, + "responses": { + "200": { + "description": "Password deleted successfully" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/v1/users/permissions": { + "get": { + "summary": "Get all role permissions", + "description": "Get all management roles along with API and UI permissions", + "operationId": "get_roles_with_permissions", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [] + } + ], + "responses": { + "200": { + "description": "Role permissions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RolesWithPermissions" + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + } + } + } + }, + "/v1/users/permissions/{role}": { + "get": { + "summary": "Get permissions for a specific role", + "description": "Get API and UI permissions for a specific management role", + "operationId": "get_role_with_permissions_by_role_name", + "tags": [ + "Users" + ], + "security": [ + { + "Auth": [] + } + ], + "parameters": [ + { + "name": "role", + "in": "path", + "description": "The role name", + "required": true, + "schema": { + "type": "string" + }, + "example": "admin" + } + ], + "responses": { + "200": { + "description": "Role permissions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RolesWithPermissions" + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + } + }, + "components": { + "schemas": { + "JWT": { + "required": [ + "token", + "uid" + ], + "properties": { + "token": { + "type": "string", + "description": "Generated JWT" + }, + "uid": { + "type": "string", + "description": "Uid of user" + } + } + }, + "Error": { + "required": [ + "error_code", + "description", + "status_code" + ], + "properties": { + "error_code": { + "type": "string", + "description": "Semantic error code (e.g., password_not_complex)" + }, + "description": { + "type": "string", + "description": "Human-readable error description" + }, + "status_code": { + "type": "integer", + "x-go-json-ignore": true + } + } + }, + "Database": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id of the Database" + }, + "name": { + "type": "string", + "description": "Name of the Database" + } + } + }, + "FeatureFlag": { + "type": "object", + "description": "A configuration object that represents a Feature Flag following OpenFeature specification, which can be used to enable or disable features with variants and targeting rules.", + "properties": { + "state": { + "type": "string", + "description": "The state of the feature flag.", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "variants": { + "type": "object", + "description": "A map of variant names to their values. Values can be of any type (boolean, string, number, object).", + "additionalProperties": true + }, + "defaultVariant": { + "type": "string", + "description": "The name of the variant to use as the default when no targeting rules match." + }, + "targeting": { + "type": "object", + "description": "Optional targeting rules that determine which variant to return based on context.", + "x-omitempty": true + }, + "metadata": { + "type": "object", + "description": "Optional metadata associated with the feature flag. Keys are strings, values can be any type.", + "properties": { + "hidden": { + "type": "boolean", + "description": "When true, this flag is hidden from feature flags listings.", + "default": false + } + }, + "additionalProperties": true, + "x-omitempty": true + } + } + }, + "FeatureFlagDefinitionResponse": { + "type": "object", + "description": "A configuration object that represents a Feature Flag following OpenFeature specification, which can be used to enable or disable features with variants and targeting rules.", + "properties": { + "state": { + "type": "string", + "description": "The state of the feature flag.", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "variants": { + "type": "object", + "description": "A map of variant names to their values. Values can be of any type (boolean, string, number, object).", + "additionalProperties": true + }, + "defaultVariant": { + "type": "string", + "description": "The name of the variant to use as the default when no targeting rules match." + }, + "targeting": { + "type": "object", + "description": "Optional targeting rules that determine which variant to return based on context.", + "x-omitempty": true + }, + "metadata": { + "type": "object", + "description": "Optional metadata associated with the feature flag. Keys are strings, values can be any type.", + "additionalProperties": true, + "x-omitempty": true + } + } + }, + "FeatureFlagEvaluationResponse": { + "type": "object", + "properties": { + "value": { + "description": "The evaluated value of the feature flag (can be any type)" + }, + "key": { + "type": "string" + }, + "reason": { + "type": "string" + }, + "variant": { + "description": "The variant name that was selected (can be any type)" + }, + "metadata": { + "type": "object", + "additionalProperties": true + } + } + }, + "DatabaseHealthReport": { + "type": "object", + "required": [ + "id", + "name", + "availability", + "high_availability", + "status", + "version", + "creation_time", + "last_configured_time", + "last_backup_time", + "persistence", + "shards_placement", + "endpoints", + "shards", + "active_alerts" + ], + "properties": { + "id": { + "type": "string", + "description": "Database id" + }, + "name": { + "type": "string", + "description": "Database name" + }, + "availability": { + "$ref": "#/components/schemas/replication_status", + "description": "Whether the BDB is available (DMC is connected to all master shards)" + }, + "status": { + "enum": [ + "active", + "active-change-pending", + "pending", + "import-pending", + "delete-pending", + "recovery", + "creation-failed", + "unknown" + ], + "type": "string", + "default": "unknown", + "description": "Database life-cycle status." + }, + "version": { + "type": "string", + "description": "Database version." + }, + "creation_time": { + "type": "string", + "format": "date-time", + "description": "Database creation time." + }, + "last_configured_time": { + "type": "string", + "format": "date-time", + "description": "Database last configuration time." + }, + "last_backup_time": { + "type": "string", + "format": "date-time", + "description": "Database last backup time." + }, + "persistence": { + "type": "string", + "enum": [ + "disabled", + "aof", + "rdb" + ], + "default": "disabled", + "description": "Database persistence type." + }, + "shards_placement": { + "type": "string", + "enum": [ + "dense", + "sparse" + ], + "description": "Database shards placement." + }, + "endpoints": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Endpoint" + }, + "description": "Database endpoints." + }, + "shards": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ShardHealthReport" + }, + "description": "Database shards." + }, + "state_machine": { + "type": "object", + "$ref": "#/components/schemas/StateMachine", + "description": "Currently active state machine for the database" + }, + "active_alerts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Alert" + }, + "description": "List of active alerts for the database" + }, + "high_availability": { + "type": "object", + "$ref": "#/components/schemas/HighAvailability" + } + } + }, + "HighAvailability": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "description": "Whether every replica of the BDB is healthy", + "$ref": "#/components/schemas/replication_status" + } + } + }, + "ShardHealthReport": { + "type": "object", + "required": [ + "id", + "role", + "status", + "detailed_status" + ], + "properties": { + "id": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "leader", + "follower" + ], + "description": "shard role can be leader or follower" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "trimming" + ], + "description": "shard status can be up or trimming" + }, + "detailed_status": { + "type": "string", + "enum": [ + "ok", + "importing", + "timeout", + "loading", + "busy", + "down", + "trimming", + "unknown" + ], + "description": "shard detailed status" + } + } + }, + "ClusterHealthReport": { + "description": "Cluster health report.", + "type": "object", + "required": [ + "fqdn", + "status", + "license", + "certificates", + "nodes", + "active_alerts" + ], + "properties": { + "fqdn": { + "type": "string", + "description": "Cluster FQDN" + }, + "status": { + "type": "string", + "enum": [ + "quorum", + "quorum loss" + ], + "description": "Cluster status" + }, + "license": { + "$ref": "#/components/schemas/LicenseHealthReport" + }, + "certificates": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Certificate" + }, + "description": "List of certificates in the cluster" + }, + "nodes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Node" + }, + "description": "List of nodes in the cluster" + }, + "active_alerts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Alert" + } + } + } + }, + "LicenseHealthReport": { + "description": "License health report.", + "type": "object", + "required": [ + "expired", + "shards_in_use", + "shards_limit" + ], + "properties": { + "expired": { + "type": "boolean", + "description": "Whether the license has expired" + }, + "shards_in_use": { + "type": "integer", + "description": "Accumulated number of shards in use by databases in the cluster" + }, + "shards_limit": { + "type": "integer", + "description": "Shards limit specified in cluster license" + } + } + }, + "Certificate": { + "description": "Certificate information.", + "type": "object", + "required": [ + "type", + "expired", + "valid_until" + ], + "properties": { + "type": { + "type": "string", + "description": "Certificate type" + }, + "expired": { + "type": "boolean", + "description": "Whether the certificate has expired" + }, + "valid_until": { + "type": "string", + "format": "date-time", + "description": "Certificate expiration time" + } + } + }, + "Node": { + "description": "Node information.", + "type": "object", + "required": [ + "id", + "status", + "role", + "version", + "shards", + "memory", + "observed_at", + "services" + ], + "properties": { + "id": { + "type": "string", + "description": "Node id" + }, + "status": { + "type": "string", + "description": "Node status" + }, + "role": { + "type": "string", + "description": "Node role can be leader or follower", + "enum": [ + "leader", + "follower" + ] + }, + "version": { + "type": "string", + "description": "RS version installed on the node" + }, + "shards": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ShardHealthReport" + }, + "description": "Shards on the node." + }, + "memory": { + "type": "object", + "$ref": "#/components/schemas/Memory", + "description": "Memory information regarding the node" + }, + "observed_at": { + "type": "integer", + "format": "int64", + "description": "Unix time in seconds when the value was last written in the CCS" + }, + "services": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "Service": { + "description": "Services running on the node managed by supervisor", + "type": "object", + "required": [ + "name", + "status" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the service" + }, + "status": { + "type": "string", + "description": "Status of the service corresponding to the statename returned by supervisor" + } + } + }, + "Memory": { + "description": "Memory information", + "type": "object", + "required": [ + "total", + "free", + "provision_ram", + "migration_threshold" + ], + "properties": { + "total": { + "type": "integer", + "format": "int64", + "description": "Total memory in bytes" + }, + "free": { + "type": "integer", + "format": "int64", + "description": "Free memory in bytes" + }, + "provision_ram": { + "type": "integer", + "format": "int64", + "description": "Minimum free ram to allow provisioning of a new shard on the node" + }, + "migration_threshold": { + "type": "integer", + "format": "int64", + "description": "Minimum free ram to allow migration of a new shard to the node" + } + } + }, + "Alert": { + "description": "Alert information", + "type": "object", + "required": [ + "name", + "active_since" + ], + "properties": { + "name": { + "type": "string", + "description": "Alert name" + }, + "active_since": { + "type": "string", + "format": "date-time", + "description": "Since what time the alert is active" + } + } + }, + "Endpoint": { + "description": "Endpoint information", + "type": "object", + "required": [ + "name", + "availability" + ], + "properties": { + "name": { + "type": "string", + "description": "Endpoint name" + }, + "availability": { + "description": "Whether the endpoint is available as reported by Node WD", + "$ref": "#/components/schemas/replication_status" + } + } + }, + "replication_status": { + "description": "The replication link status", + "type": "string", + "enum": [ + "down", + "up" + ] + }, + "StateMachine": { + "description": "State machine information", + "type": "object", + "required": [ + "name", + "state" + ], + "properties": { + "name": { + "type": "string", + "description": "State machine name" + }, + "state": { + "type": "string", + "description": "State machine state" + } + } + }, + "Migration": { + "type": "object", + "description": "Object structure for migration status.", + "properties": { + "status": { + "description": "Sync status of this source.", + "type": "string", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "lag": { + "description": "Lag in milliseconds between source and destination (while synced).", + "type": "integer", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "rdb_size": { + "description": "Number of source bytes.", + "type": "integer", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "rdb_transferred": { + "description": "Number of source bytes transferred.", + "type": "integer", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "run_id": { + "description": "Syncer run id.", + "type": "string", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "flush_counter": { + "description": "How many times syncer had to restart.", + "type": "integer", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "source_shards": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/SourceShard" + } + }, + "error": { + "$ref": "#/components/schemas/MigrationError", + "nullable": true, + "readOnly": true, + "x-omitempty": true + } + } + }, + "SourceShard": { + "type": "object", + "description": "Replication shard with its metadata", + "properties": { + "replication_id": { + "description": "Replication id", + "type": "string", + "readOnly": true + }, + "replication_offset": { + "description": "Replication offset", + "type": "integer", + "readOnly": true + } + } + }, + "MigrationError": { + "type": "object", + "description": "Error information for migration operations", + "properties": { + "error_code": { + "description": "Error code identifying the specific error", + "type": "string", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "message": { + "description": "Human-readable error message", + "type": "string", + "nullable": true, + "readOnly": true, + "x-omitempty": true + }, + "timestamp": { + "description": "Timestamp when the error occurred", + "type": "string", + "nullable": true, + "format": "date-time", + "readOnly": true, + "x-omitempty": true + } + } + }, + "MigrationResponse": { + "type": "object", + "description": "Response wrapper for migration endpoint", + "properties": { + "migration": { + "$ref": "#/components/schemas/Migration" + } + } + }, + "User": { + "type": "object", + "description": "An API object that represents an Redis Enterprise Cluster user.", + "required": [ + "uid", + "name", + "role", + "role_uids", + "auth_method" + ], + "properties": { + "uid": { + "description": "User's unique uid.", + "type": "integer", + "x-go-type": "json.Number" + }, + "email": { + "description": "User's email. (pattern matching only ascii characters)", + "type": "string" + }, + "password": { + "description": "User's password. Note that it could also be an already-hashed value, in which case 'password_hash_method' parameter is also provided.", + "type": "string" + }, + "name": { + "description": "User's name. (pattern does not allow non ascii and special characters &,<,>,\")", + "type": "string" + }, + "email_alerts": { + "description": "Activate email alerts for a user.", + "type": "boolean", + "default": true + }, + "bdbs_email_alerts": { + "description": "UIDs of databases that user will receive alerts for.", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "cluster_email_alerts": { + "description": "Activate cluster email alerts for a user.", + "type": "boolean" + }, + "auth_method": { + "type": "string", + "enum": [ + "regular", + "certificate", + "entraid", + "sso" + ] + }, + "certificate_subject_line": { + "description": "The certificate's subject line as defined by RFC2253 (for certificate based authentication users only)", + "type": "string" + }, + "password_issue_date": { + "description": "The date in which the password was set.", + "type": "string", + "format": "date-time" + }, + "last_login": { + "description": "Timestamp of the user's last login time. This denotes the last time an authentication with the user's credentials was successful.", + "type": "integer", + "format": "int64" + }, + "role": { + "description": "(deprecated) User's role.", + "x-deprecated-reason": "Use role_uids instead", + "deprecated": true, + "allOf": [ + { + "$ref": "#/components/schemas/UserRole" + } + ] + }, + "role_uids": { + "description": "List of role uids associated with the user", + "type": "array", + "items": { + "type": "integer", + "x-go-type": "json.Number" + } + }, + "account_id": { + "description": "SM account ID", + "type": "integer" + }, + "action_uid": { + "description": "Action uid. If exists - progress can be tracked by the GET /actions/ API", + "type": "string" + }, + "status": { + "description": "Status of the user.", + "type": "string", + "enum": [ + "active", + "locked", + "password_expired" + ], + "x-enum-varnames": [ + "Active", + "Locked", + "PasswordExpired" + ] + } + }, + "example": { + "password_issue_date": "2025-03-02T09:43:34Z", + "last_login": 1760618047, + "email": "user@redis.com", + "name": "John Doe", + "email_alerts": true, + "auth_method": "regular", + "role_uids": [ + 1 + ], + "status": "active" + } + }, + "UserRequest": { + "type": "object", + "description": "User modification request.", + "properties": { + "name": { + "description": "User's name.", + "type": "string", + "pattern": "^[^&<>\"]*$", + "maxLength": 255, + "minLength": 1 + }, + "email": { + "description": "User's email.", + "type": "string", + "format": "email" + }, + "password": { + "description": "User's password for regular authentication. Required for regular auth method.", + "type": "string" + }, + "email_alerts": { + "description": "Activate email alerts for a user.", + "type": "boolean" + }, + "bdbs_email_alerts": { + "description": "UIDs of databases that user will receive alerts for.", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "cluster_email_alerts": { + "description": "Activate cluster email alerts for a user.", + "type": "boolean" + }, + "auth_method": { + "type": "string", + "enum": [ + "regular", + "certificate", + "entraid", + "sso" + ] + }, + "certificate_subject_line": { + "description": "The certificate's subject line as defined by RFC2253 (for certificate based authentication users only)", + "type": "string" + }, + "role": { + "description": "(deprecated) User's role.", + "x-deprecated-reason": "Use role_uids instead", + "x-sunset": "2027-12-31", + "deprecated": true, + "allOf": [ + { + "$ref": "#/components/schemas/UserRole" + } + ] + }, + "role_uids": { + "description": "List of role uids associated with the user", + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "x-go-type": "json.Number" + } + }, + "account_id": { + "description": "SM account ID", + "type": "integer" + }, + "password_hash_method": { + "$ref": "#/components/schemas/PasswordHashMethod" + } + } + }, + "PasswordHashMethod": { + "type": "integer", + "description": "Used when password is passed pre-hashed", + "enum": [ + 1 + ], + "x-enum-varnames": [ + "PreHashed" + ] + }, + "UserRole": { + "type": "string", + "description": "User's management role", + "enum": [ + "admin", + "user_manager", + "cluster_member", + "db_viewer", + "db_member", + "cluster_viewer", + "none" + ] + }, + "Permissions": { + "type": "object", + "description": "API and UI permissions for a role", + "properties": { + "api_permissions": { + "type": "array", + "description": "List of permission strings", + "items": { + "type": "string" + } + }, + "ui_permissions": { + "type": "array", + "description": "List of permission strings", + "items": { + "type": "string" + } + } + }, + "example": { + "api_permissions": [ + "create_node", + "update_node", + "delete_node" + ], + "ui_permissions": [ + "view_cluster_page", + "view_database_page" + ] + } + }, + "RolesWithPermissions": { + "type": "object", + "description": "A map of role names to their permissions", + "additionalProperties": { + "$ref": "#/components/schemas/Permissions" + }, + "example": { + "admin": { + "api_permissions": [ + "create_node", + "update_node", + "delete_node" + ], + "ui_permissions": [ + "view_cluster_page", + "view_database_page" + ] + }, + "db_viewer": { + "api_permissions": [ + "view_bdb_info", + "view_all_bdbs_info" + ], + "ui_permissions": [ + "view_database_page" + ] + } + } + } + }, + "responses": { + "BadRequest": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "NotFound": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "Unauthorized": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "Forbidden": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "InternalServerError": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "ServiceUnavailable": { + "description": "Service Unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "NotAcceptable": { + "description": "Not Acceptable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "securitySchemes": { + "Auth": { + "type": "apiKey", + "in": "header", + "name": "r-auth-user" + } + } + } +} \ No newline at end of file From c42caac58fd755f93b4c5503f15bab607cf52f02 Mon Sep 17 00:00:00 2001 From: sonya-spasova Date: Mon, 24 Nov 2025 17:31:19 +0200 Subject: [PATCH 3/6] address comments to move content --- README.md | 4 +- .../rest-api}/api-reference.md | 2 +- .../rest-api}/api-reference/openapi.json | 1436 ++++++----------- 3 files changed, 489 insertions(+), 953 deletions(-) rename content/operate/rs/{api => references/rest-api}/api-reference.md (95%) rename content/operate/rs/{api => references/rest-api}/api-reference/openapi.json (57%) diff --git a/README.md b/README.md index 69dc3a6a28..1c16b7395c 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,4 @@ nil pointer evaluating page.Page.Params ``` This happened for us when Hugo executed the `bannerText` logic, which inspected all parent pages by checking if they have a banner text set. The problem was that one of the parent folders was missing an `_index.md` file, which meant the folder couldn't be identified as a page. The solution was to add an `_index.md` file to the folder that didn't have it yet. - - -<> \ No newline at end of file + \ No newline at end of file diff --git a/content/operate/rs/api/api-reference.md b/content/operate/rs/references/rest-api/api-reference.md similarity index 95% rename from content/operate/rs/api/api-reference.md rename to content/operate/rs/references/rest-api/api-reference.md index 6e15ca75ac..eb8266822c 100644 --- a/content/operate/rs/api/api-reference.md +++ b/content/operate/rs/references/rest-api/api-reference.md @@ -3,4 +3,4 @@ Title: Redis Enterprise API linkTitle: API reference layout: apireference type: page ---- +--- \ No newline at end of file diff --git a/content/operate/rs/api/api-reference/openapi.json b/content/operate/rs/references/rest-api/api-reference/openapi.json similarity index 57% rename from content/operate/rs/api/api-reference/openapi.json rename to content/operate/rs/references/rest-api/api-reference/openapi.json index 1d1065dbf9..29cd41906f 100644 --- a/content/operate/rs/api/api-reference/openapi.json +++ b/content/operate/rs/references/rest-api/api-reference/openapi.json @@ -11,393 +11,10 @@ } ], "paths": { - "/v4/auth/authorize": { - "get": { - "summary": "Authorized a request and returns a token", - "description": "Authorized a request and returns a token", - "operationId": "authorize", - "tags": [ - "Auth" - ], - "parameters": [ - { - "name": "ttl", - "in": "query", - "required": false, - "schema": { - "type": "integer" - }, - "description": "Time-to-live (TTL) of the token in seconds" - } - ], - "responses": { - "200": { - "description": "Token response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JWT" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "500": { - "$ref": "#/components/responses/InternalServerError" - } - } - } - }, - "/v4/cluster/health": { - "get": { - "summary": "Get cluster health report.", - "description": "Cluster health report.", - "operationId": "cluster_health_report", - "tags": [ - "Cluster" - ], - "parameters": [ - { - "name": "issues_only", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - }, - "description": "indicate to return only resources with unhealthy status" - } - ], - "responses": { - "200": { - "description": "Cluster report is ready see detailed information.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClusterHealthReport" - } - } - } - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - } - }, - "/v4/bdb/{db_id}/health": { - "get": { - "summary": "Get database health report.", - "description": "Database health check indication.", - "operationId": "database_health_report", - "tags": [ - "Database" - ], - "security": [ - { - "Auth": [ - "view_bdb_info" - ] - } - ], - "parameters": [ - { - "name": "db_id", - "in": "path", - "description": "database ID", - "required": true, - "schema": { - "type": "string", - "maxLength": 3 - } - }, - { - "name": "issues_only", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - }, - "description": "indicate to return only resources with unhealthy status" - } - ], - "responses": { - "200": { - "description": "Database report is ready see detailed information.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DatabaseHealthReport" - } - } - } - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - } - }, - "/v4/feature-flags/flags/definition": { - "get": { - "summary": "Get feature flags list.", - "description": "List of available feature flags.", - "operationId": "get_feature_flags", - "tags": [ - "FeatureFlags" - ], - "responses": { - "200": { - "description": "List of feature flags.", - "content": { - "application/json": { - "schema": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/FeatureFlagDefinitionResponse" - } - } - } - } - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - } - }, - "/v4/feature-flags/flags/definition/{flag_name}": { - "get": { - "summary": "Get single feature flag.", - "description": "Get single feature flag by unique name.", - "operationId": "get_feature_flag", - "tags": [ - "FeatureFlags" - ], - "parameters": [ - { - "name": "flag_name", - "in": "path", - "description": "The feature flag name", - "required": true, - "schema": { - "type": "string", - "x-go-type": "string" - }, - "example": "test-flag" - } - ], - "responses": { - "200": { - "description": "Feature flag information.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FeatureFlagDefinitionResponse" - } - } - } - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - }, - "put": { - "summary": "Update feature flag.", - "description": "Update feature flag by unique name.", - "operationId": "update_feature_flag", - "tags": [ - "FeatureFlags" - ], - "parameters": [ - { - "name": "flag_name", - "in": "path", - "description": "The feature flag name", - "required": true, - "schema": { - "type": "string", - "x-go-type": "string" - }, - "example": "test-flag" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "additionalProperties": false, - "anyOf": [ - { - "required": [ - "defaultVariant" - ] - }, - { - "required": [ - "targeting" - ] - } - ], - "properties": { - "defaultVariant": { - "type": "string", - "description": "The name of the variant to use as the default when no targeting rules match." - }, - "targeting": { - "type": "object", - "description": "Optional targeting rules that determine which variant to return based on context. Keys are strings, values can be any type.", - "additionalProperties": true - } - } - } - } - } - }, - "responses": { - "200": { - "description": "Feature flag updated.", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - } - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - } - }, - "/v4/feature-flags/flags/evaluation/{flag_name}": { - "post": { - "summary": "Evaluate feature flag by context.", - "description": "Evaluate feature flag by context.", - "operationId": "evaluate_feature_flag", - "tags": [ - "FeatureFlags" - ], - "parameters": [ - { - "name": "flag_name", - "in": "path", - "description": "The feature flag name", - "required": true, - "schema": { - "type": "string" - }, - "example": "test-flag" - } - ], - "requestBody": { - "required": false, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "context": { - "type": "object", - "description": "Optional context object containing key-value pairs for targeting evaluation.", - "additionalProperties": true - } - } - } - } - } - }, - "responses": { - "200": { - "description": "Feature flag evaluation result.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FeatureFlagEvaluationResponse" - } - } - } - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - } - }, - "/v4/feature-flags/profiles/current": { - "put": { - "summary": "Update current profile.", - "description": "Update current profile by name.", - "operationId": "update_current_profile", - "tags": [ - "FeatureFlags" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "profile" - ], - "properties": { - "profile": { - "type": "string", - "minLength": 1, - "maxLength": 50, - "pattern": "^[a-zA-Z0-9_-]+$", - "description": "The name of the profile, that will be used to update the current profile." - } - } - } - } - } - }, - "responses": { - "200": { - "description": "Feature flags updating current profile.", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "503": { - "$ref": "#/components/responses/ServiceUnavailable" - } - } - } - }, "/v1/migrations/{uid}": { "get": { "x-stability-level": "stable", + "x-publish-docs": true, "summary": "Get migration status of a bdb in the cluster", "description": "Migration status of a bdb in the cluster", "operationId": "get_migration", @@ -443,571 +60,6 @@ } } } - }, - "/v1/users/role": { - "get": { - "summary": "Get the management role of the authenticating user.", - "description": "Get the management role of the authenticating user.", - "operationId": "get_user_role", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [] - } - ], - "responses": { - "200": { - "description": "User role information", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "role": { - "$ref": "#/components/schemas/UserRole" - } - } - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - } - } - } - }, - "/v1/users/{uid}": { - "get": { - "summary": "Get a single Redis Enterprise Cluster user", - "description": "Get a single user by unique ID", - "operationId": "get_user", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [ - "view_user_info" - ] - } - ], - "parameters": [ - { - "name": "uid", - "in": "path", - "description": "The user unique ID", - "required": true, - "schema": { - "type": "integer", - "x-go-type": "json.Number" - }, - "example": 1 - } - ], - "responses": { - "200": { - "description": "User information", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - }, - "delete": { - "summary": "Delete a Redis Enterprise Cluster user", - "description": "Delete a user by unique ID", - "operationId": "delete_user", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [ - "delete_user" - ] - } - ], - "parameters": [ - { - "name": "uid", - "in": "path", - "description": "The user unique ID", - "required": true, - "schema": { - "type": "integer", - "x-go-type": "json.Number" - }, - "example": 1 - } - ], - "responses": { - "200": { - "description": "User deleted successfully", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "action_uid": { - "type": "string", - "description": "Action uid for tracking progress" - } - }, - "example": { - "action_uid": "12345-abcde-67890" - } - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "406": { - "$ref": "#/components/responses/NotAcceptable" - } - } - }, - "put": { - "summary": "Update a Redis Enterprise Cluster user", - "description": "Update a user configuration by unique ID", - "operationId": "update_user", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [ - "update_user" - ] - } - ], - "parameters": [ - { - "name": "uid", - "in": "path", - "description": "The user unique ID", - "required": true, - "schema": { - "type": "integer", - "x-go-type": "json.Number" - }, - "example": 1 - }, - { - "name": "dry_run", - "in": "query", - "description": "Validate the request without persisting changes", - "required": false, - "schema": { - "type": "boolean" - } - } - ], - "requestBody": { - "description": "User update data", - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - }, - "example": { - "name": "Jane Poe", - "email_alerts": false - } - } - } - }, - "responses": { - "200": { - "description": "User updated successfully", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "406": { - "$ref": "#/components/responses/NotAcceptable" - } - } - } - }, - "/v1/users": { - "get": { - "summary": "Get all Redis Enterprise Cluster users", - "description": "Get all Redis Enterprise Cluster users in the cluster", - "operationId": "get_users", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [ - "view_all_users_info" - ] - } - ], - "responses": { - "200": { - "description": "List of users", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - } - } - }, - "post": { - "summary": "Create a new Redis Enterprise Cluster user", - "description": "Create a new user with the provided configuration", - "operationId": "create_user", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [ - "create_new_user" - ] - } - ], - "parameters": [ - { - "name": "dry_run", - "in": "query", - "description": "Validate the request without persisting changes", - "required": false, - "schema": { - "type": "boolean" - } - } - ], - "requestBody": { - "description": "User creation data", - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserRequest" - } - } - } - }, - "responses": { - "200": { - "description": "User created successfully", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "409": { - "description": "User with the same email or name already exists", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, - "/v1/users/password": { - "put": { - "summary": "Reset user password", - "description": "Reset the password list of a user to include a single new password", - "operationId": "reset_user_password", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [] - } - ], - "requestBody": { - "description": "Password reset data", - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "username": { - "type": "string", - "description": "The username of the affected user. If missing, defaults to authenticated user" - }, - "new_password": { - "type": "string", - "description": "The new password" - }, - "password_hash_method": { - "$ref": "#/components/schemas/PasswordHashMethod" - } - }, - "required": [ - "new_password" - ] - }, - "example": { - "username": "john.doe", - "new_password": "new-secure-password" - } - } - } - }, - "responses": { - "200": { - "description": "Password reset successfully" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - }, - "post": { - "summary": "Add user password", - "description": "Add a new password to a user's passwords list", - "operationId": "add_user_password", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [] - } - ], - "requestBody": { - "description": "Password addition data", - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "username": { - "type": "string", - "description": "The username of the affected user. If missing, defaults to authenticated user" - }, - "new_password": { - "type": "string", - "description": "A password to add" - }, - "password_hash_method": { - "$ref": "#/components/schemas/PasswordHashMethod" - } - }, - "required": [ - "new_password" - ] - }, - "example": { - "username": "john.doe", - "new_password": "additional-password" - } - } - } - }, - "responses": { - "200": { - "description": "Password added successfully" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - }, - "delete": { - "summary": "Delete user password", - "description": "Delete a password from the list of a user's passwords", - "operationId": "delete_user_password", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [] - } - ], - "requestBody": { - "description": "Password deletion data", - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "username": { - "type": "string", - "description": "The username of the affected user. If missing, defaults to authenticated user" - }, - "old_password": { - "type": "string", - "description": "An existing password to delete" - } - }, - "required": [ - "old_password" - ] - }, - "example": { - "username": "john.doe", - "old_password": "password-to-remove" - } - } - } - }, - "responses": { - "200": { - "description": "Password deleted successfully" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - } - }, - "/v1/users/permissions": { - "get": { - "summary": "Get all role permissions", - "description": "Get all management roles along with API and UI permissions", - "operationId": "get_roles_with_permissions", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [] - } - ], - "responses": { - "200": { - "description": "Role permissions", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RolesWithPermissions" - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - } - } - } - }, - "/v1/users/permissions/{role}": { - "get": { - "summary": "Get permissions for a specific role", - "description": "Get API and UI permissions for a specific management role", - "operationId": "get_role_with_permissions_by_role_name", - "tags": [ - "Users" - ], - "security": [ - { - "Auth": [] - } - ], - "parameters": [ - { - "name": "role", - "in": "path", - "description": "The role name", - "required": true, - "schema": { - "type": "string" - }, - "example": "admin" - } - ], - "responses": { - "200": { - "description": "Role permissions", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RolesWithPermissions" - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - } } }, "components": { @@ -1049,6 +101,443 @@ } } }, + "Crdb": { + "type": "object", + "properties": { + "guid": { + "type": "string", + "description": "The GUID of the Active-Active database." + }, + "name": { + "type": "string", + "description": "Name of Active-Active database." + }, + "managed_by": { + "type": "string", + "description": "The component that manages the A-A database." + }, + "encryption": { + "type": "boolean", + "description": "Encrypt communication", + "default": false + }, + "default_db_config": { + "$ref": "#/components/schemas/DatabaseConfig" + }, + "volatile_config_fields": { + "description": "A list of DB config fields that will be set even if unchanged.\nThis list does not persist, and is specific for the API request it\nis part of.\n", + "type": "array", + "items": { + "type": "string" + } + }, + "local_databases": { + "description": "Mapping of instance IDs for local databases to local BDB IDs.", + "type": "array", + "readOnly": true, + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/components/schemas/InstanceId" + }, + "bdb_uid": { + "description": "Local cluster Bdatabases UID.", + "type": "string" + } + } + } + }, + "instances": { + "type": "array", + "description": "Active-Active instances.", + "items": { + "$ref": "#/components/schemas/InstanceInfo" + } + }, + "causal_consistency": { + "type": "boolean", + "description": "Enables causal consistency across crdt instances", + "default": false + }, + "featureset_version": { + "type": "integer", + "description": "Active-Active database active FeatureSet version" + }, + "protocol_version": { + "type": "integer", + "description": "Active-Active database active protocol version" + }, + "modules": { + "type": "array", + "description": "CRDB-compatible Redis modules.", + "items": { + "$ref": "#/components/schemas/Module" + } + } + } + }, + "InstanceInfo": { + "description": "Active-Active instance information.", + "type": "object", + "properties": { + "id": { + "$ref": "#/components/schemas/InstanceId" + }, + "compression": { + "type": "integer", + "description": "Compression level when syncing from this source.\n", + "minimum": 0, + "maximum": 6, + "default": 3 + }, + "cluster": { + "$ref": "#/components/schemas/ClusterInfo" + }, + "db_config": { + "$ref": "#/components/schemas/DatabaseConfig" + }, + "db_uid": { + "type": "string", + "description": "ID of local database instance. This field is likely to be\nempty for instances other than the local one.\n" + } + } + }, + "DatabaseConfig": { + "type": "object", + "properties": { + "cert": { + "type": "string", + "description": "Optional PEM-encoded server certificate for the underlying database instance." + }, + "private_key": { + "type": "string", + "description": "Optional PEM-encoded private key matching cert for the underlying database instance." + }, + "replication": { + "type": "boolean", + "description": "Database replication", + "default": true + }, + "rack_aware": { + "type": "boolean", + "description": "Require the database to be always replicated across multiple racks", + "default": false + }, + "memory_size": { + "type": "integer", + "description": "Database memory size limit, in bytes.", + "default": 0 + }, + "data_persistence": { + "description": "Database on-disk persistence", + "type": "string", + "enum": [ + "disabled", + "snapshot", + "aof" + ], + "default": "aof" + }, + "tls_mode": { + "type": "string", + "enum": [ + "disabled", + "replica_ssl", + "enabled" + ], + "default": "disabled", + "description": "Encrypt communication" + }, + "authentication_redis_pass": { + "type": "string", + "description": "Redis AUTH password" + }, + "authentication_admin_pass": { + "type": "string", + "description": "Administrative databases access token" + }, + "port": { + "type": "integer", + "description": "TCP port for database access", + "minimum": 1, + "maximum": 65535 + }, + "shards_count": { + "type": "integer", + "minimum": 1, + "maximum": 512, + "default": 1, + "description": "Number of database shards" + }, + "shard_key_regex": { + "type": "array", + "description": "Custom keyname-based sharding rules. Custom keyname-based sharding rules.\n\nTo use the default rules you should set the value to:\n [ { \\\"regex\\\": \\\".*\\\\{(?.*)\\\\}.*\\\" }, { \\\"regex\\\": \\\"(?.*)\\\" } ]\n", + "items": { + "type": "object", + "properties": { + "regex": { + "type": "string" + } + }, + "required": [ + "regex" + ] + } + }, + "oss_sharding": { + "type": "boolean", + "default": false, + "description": "An alternative to shard_key_regex for using the common case of the oss shard hashing policy" + }, + "oss_cluster": { + "type": "boolean", + "default": false, + "description": "Enables OSS Cluster mode" + }, + "proxy_policy": { + "type": "string", + "enum": [ + "single", + "all-master-shards", + "all-nodes" + ], + "description": "The policy used for proxy binding to the endpoint" + }, + "shards_placement": { + "description": "Control the density of shards: should they reside on as few or as many nodes as possible", + "type": "string", + "enum": [ + "dense", + "sparse" + ] + }, + "oss_cluster_api_preferred_ip_type": { + "type": "string", + "description": "Indicates preferred ip type in oss cluster API: internal/external", + "enum": [ + "internal", + "external" + ] + }, + "bigstore": { + "type": "boolean", + "default": false, + "description": "Database driver is Redis on Flash" + }, + "bigstore_ram_size": { + "type": "integer", + "default": 0, + "description": "Memory size of RAM size" + }, + "aof_policy": { + "type": "string", + "enum": [ + "appendfsync-every-sec", + "appendfsync-always" + ], + "default": "appendfsync-every-sec", + "description": "Policy for Append-Only File data persistence" + }, + "snapshot_policy": { + "type": "array", + "description": "Policy for snapshot-based data persistence.\n\nDataset snapshot will be taken every N secs if there are at least M writes changes in the dataset\n", + "items": { + "type": "object", + "description": "Policy criteria expressed in minimum writes in a given time window (seconds)", + "properties": { + "secs": { + "type": "integer", + "minimum": 1 + }, + "writes": { + "type": "integer", + "minimum": 1 + } + }, + "required": [ + "secs", + "writes" + ] + } + }, + "max_aof_load_time": { + "type": "integer", + "default": 3600, + "description": "Hint for maximum AOF reload time" + }, + "max_aof_file_size": { + "type": "integer", + "default": 322122547200, + "description": "Hint for maximum AOF file size" + } + } + }, + "ClusterInfo": { + "type": "object", + "description": "Configuration details of a cluster that is part of a multi-master\ndatabase.\n", + "properties": { + "name": { + "type": "string", + "description": "Cluster fully qualified name, used to unique identify the cluster.\n\nTypically this is the same as the hostname used in the URL, although\nin some configruations the URL may point to a different name/address.\n" + }, + "url": { + "type": "string", + "description": "Cluster access URL." + }, + "replication_endpoint": { + "type": "string", + "description": "Address to use for peer replication.\n\nIf not specified, it is assumed that standard cluster naming conventions apply.\n" + }, + "replication_tls_sni": { + "type": "string", + "description": "Cluster SNI for TLS connections." + }, + "credentials": { + "type": "object", + "description": "Cluster access credentials.", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "required": [ + "username", + "password" + ] + } + } + }, + "Module": { + "type": "object", + "description": "Configuration details of a module that runs in a multi-master\ndatabase.\n", + "properties": { + "module_name": { + "type": "string", + "description": "Module name" + }, + "featureset_version": { + "type": "integer", + "minimum": 0, + "description": "Module featureset version." + } + }, + "required": [ + "module_name", + "featureset_version" + ] + }, + "Task": { + "type": "object", + "description": "An administrative task that gets invoked as a result of a user request.\n", + "properties": { + "id": { + "type": "string", + "readOnly": true + }, + "crdb_guid": { + "type": "string", + "readOnly": true + }, + "started": { + "type": "string", + "format": "date-time", + "example": "2018-03-20T09:12:28Z", + "readOnly": true + }, + "ended": { + "type": "string", + "format": "date-time", + "example": "2018-03-20T09:12:28Z", + "readOnly": true + }, + "worker_name": { + "type": "string", + "readOnly": true, + "description": "The worker that executes the task." + }, + "operation": { + "type": "string", + "readOnly": true, + "description": "The operation that is running." + }, + "status": { + "type": "string", + "readOnly": true, + "description": "Options:\n\nqueued\n\nstarted\n\nfinished\n\nfailed\n" + }, + "progress": { + "type": "object", + "readOnly": true, + "description": "Shows what the task is doing when its status is started", + "properties": { + "worker": { + "type": "string", + "description": "The step the worker is executing" + }, + "clusters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The instance cluster name" + }, + "progress": { + "type": "string", + "description": "The step the instance coordinator is executing" + } + } + } + } + } + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "cluster_name": { + "type": "string", + "description": "Cluster on which error occurred." + }, + "error_code": { + "type": "string", + "description": "Returned or generated error code." + }, + "description": { + "type": "string", + "description": "Returned or generated error description." + } + } + } + } + } + }, + "ErrorDetails": { + "type": "object", + "description": "Error response details.", + "properties": { + "error_code": { + "type": "string", + "description": "Returned or generated error code." + }, + "description": { + "type": "string", + "description": "Returned or generated error description." + } + } + }, + "InstanceId": { + "type": "integer", + "minimum": 1, + "maximum": 31, + "description": "Unique instance ID." + }, "Database": { "required": [ "id", @@ -1715,6 +1204,55 @@ } } }, + "RedisAcl": { + "type": "object", + "description": "An API object that represents a Redis ACL definition.", + "required": [ + "uid", + "name", + "acl", + "min_version", + "max_version" + ], + "properties": { + "uid": { + "description": "Redis ACL unique uid.", + "type": "integer", + "x-go-type": "json.Number" + }, + "name": { + "description": "ACL name.", + "type": "string" + }, + "acl": { + "description": "Redis ACL string definition.", + "type": "string" + }, + "min_version": { + "description": "Minimum Redis version for which this ACL is valid.", + "type": "string" + }, + "max_version": { + "description": "Maximum Redis version for which this ACL is valid.", + "type": "string" + }, + "account_id": { + "description": "SM account ID associated with this ACL.", + "type": "integer" + }, + "action_uid": { + "description": "Action uid. If exists - progress can be tracked by the GET /actions/ API", + "type": "string" + } + }, + "example": { + "uid": 1, + "name": "default", + "acl": "on >allcommands allkeys", + "min_version": "6.2", + "max_version": "9999" + } + }, "User": { "type": "object", "description": "An API object that represents an Redis Enterprise Cluster user.", From 28a2b5be33e43e4511a79f843174495a9555eff6 Mon Sep 17 00:00:00 2001 From: sonya-spasova Date: Tue, 25 Nov 2025 14:35:46 +0200 Subject: [PATCH 4/6] regenerate openapi.json --- .../rest-api/api-reference/openapi.json | 108 +++++++++++++----- 1 file changed, 80 insertions(+), 28 deletions(-) diff --git a/content/operate/rs/references/rest-api/api-reference/openapi.json b/content/operate/rs/references/rest-api/api-reference/openapi.json index 29cd41906f..b0a6526805 100644 --- a/content/operate/rs/references/rest-api/api-reference/openapi.json +++ b/content/operate/rs/references/rest-api/api-reference/openapi.json @@ -7,7 +7,7 @@ }, "servers": [ { - "url": "http://localhost:3346" + "url": "http://localhost:9443" } ], "paths": { @@ -999,31 +999,37 @@ "description": "Memory information", "type": "object", "required": [ - "total", - "free", - "provision_ram", - "migration_threshold" + "total_ram", + "free_ram", + "free_provisional_ram", + "total_provisional_ram", + "overbooking_depth" ], "properties": { - "total": { + "total_ram": { "type": "integer", "format": "int64", - "description": "Total memory in bytes" + "description": "Total ram the node has in bytes" }, - "free": { + "free_ram": { "type": "integer", "format": "int64", - "description": "Free memory in bytes" + "description": "Free ram the node has in bytes" }, - "provision_ram": { + "free_provisional_ram": { "type": "integer", "format": "int64", - "description": "Minimum free ram to allow provisioning of a new shard on the node" + "description": "Remaining ram for provisioning new shards on the node" }, - "migration_threshold": { + "total_provisional_ram": { "type": "integer", "format": "int64", - "description": "Minimum free ram to allow migration of a new shard to the node" + "description": "Total ram for provisioning shards on the node" + }, + "overbooking_depth": { + "type": "integer", + "format": "int64", + "description": "How much the node is overbooked or has capacity remaining, like free provisional ram but takes into account shards_overbooking (can be negative if it is overbooked)" } } }, @@ -1253,6 +1259,65 @@ "max_version": "9999" } }, + "RoleName": { + "type": "string", + "description": "Name of the management role.", + "enum": [ + "admin", + "user_manager", + "cluster_member", + "db_viewer", + "db_member", + "cluster_viewer", + "none" + ] + }, + "RoleBody": { + "type": "object", + "description": "Common role properties shared across role payloads.", + "properties": { + "name": { + "description": "Role's name.", + "type": "string", + "pattern": "^[a-zA-Z0-9_ \\[\\]()@,.;#-]+$" + }, + "management": { + "$ref": "#/components/schemas/RoleName" + }, + "account_id": { + "description": "Account ID. Only applicable to account-scoped roles.", + "type": "integer" + } + } + }, + "Role": { + "description": "An API object that represents a Redis Enterprise role.", + "allOf": [ + { + "$ref": "#/components/schemas/RoleBody" + }, + { + "type": "object", + "required": [ + "uid", + "name", + "management" + ], + "properties": { + "uid": { + "description": "Role's unique uid.", + "type": "integer", + "x-go-type": "json.Number" + } + } + } + ], + "example": { + "uid": 1, + "name": "DBA", + "management": "admin" + } + }, "User": { "type": "object", "description": "An API object that represents an Redis Enterprise Cluster user.", @@ -1327,7 +1392,7 @@ "deprecated": true, "allOf": [ { - "$ref": "#/components/schemas/UserRole" + "$ref": "#/components/schemas/RoleName" } ] }, @@ -1431,7 +1496,7 @@ "deprecated": true, "allOf": [ { - "$ref": "#/components/schemas/UserRole" + "$ref": "#/components/schemas/RoleName" } ] }, @@ -1464,19 +1529,6 @@ "PreHashed" ] }, - "UserRole": { - "type": "string", - "description": "User's management role", - "enum": [ - "admin", - "user_manager", - "cluster_member", - "db_viewer", - "db_member", - "cluster_viewer", - "none" - ] - }, "Permissions": { "type": "object", "description": "API and UI permissions for a role", From d30e3bf9a91099f0311cebfc8479e94c5c9d1b12 Mon Sep 17 00:00:00 2001 From: sonya-spasova Date: Tue, 2 Dec 2025 18:45:11 +0200 Subject: [PATCH 5/6] address comments --- .../rest-api/api-reference/openapi.json | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/content/operate/rs/references/rest-api/api-reference/openapi.json b/content/operate/rs/references/rest-api/api-reference/openapi.json index b0a6526805..1162da43a4 100644 --- a/content/operate/rs/references/rest-api/api-reference/openapi.json +++ b/content/operate/rs/references/rest-api/api-reference/openapi.json @@ -7,7 +7,7 @@ }, "servers": [ { - "url": "http://localhost:9443" + "url": "https://localhost:9443" } ], "paths": { @@ -1263,13 +1263,13 @@ "type": "string", "description": "Name of the management role.", "enum": [ - "admin", - "user_manager", - "cluster_member", + "none", "db_viewer", - "db_member", "cluster_viewer", - "none" + "db_member", + "cluster_member", + "user_manager", + "admin" ] }, "RoleBody": { @@ -1282,6 +1282,7 @@ "pattern": "^[a-zA-Z0-9_ \\[\\]()@,.;#-]+$" }, "management": { + "description": "Role's management role.", "$ref": "#/components/schemas/RoleName" }, "account_id": { @@ -1318,6 +1319,28 @@ "management": "admin" } }, + "RoleCreateRequest": { + "description": "Role creation request payload.", + "allOf": [ + { + "$ref": "#/components/schemas/RoleBody" + }, + { + "type": "object", + "properties": { + "uid": { + "description": "Optional uid to assign to the role.", + "type": "integer", + "x-go-type": "json.Number" + } + } + } + ], + "example": { + "name": "Support Engineer", + "management": "cluster_viewer" + } + }, "User": { "type": "object", "description": "An API object that represents an Redis Enterprise Cluster user.", @@ -1419,11 +1442,6 @@ "active", "locked", "password_expired" - ], - "x-enum-varnames": [ - "Active", - "Locked", - "PasswordExpired" ] } }, @@ -1660,6 +1678,16 @@ } } } + }, + "Conflict": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } } }, "securitySchemes": { From fabb0028364e25d94db111acc2a68ff35831d1f2 Mon Sep 17 00:00:00 2001 From: sonya-spasova Date: Wed, 10 Dec 2025 17:06:39 +0200 Subject: [PATCH 6/6] remove migrations,add authentication --- .../rest-api/api-reference/openapi.json | 1756 ++--------------- 1 file changed, 149 insertions(+), 1607 deletions(-) diff --git a/content/operate/rs/references/rest-api/api-reference/openapi.json b/content/operate/rs/references/rest-api/api-reference/openapi.json index 1162da43a4..48251dd6af 100644 --- a/content/operate/rs/references/rest-api/api-reference/openapi.json +++ b/content/operate/rs/references/rest-api/api-reference/openapi.json @@ -1,9 +1,9 @@ { - "openapi": "3.0.0", + "openapi": "3.0.3", "info": { - "version": "1.0.0", - "title": "Cluster API", - "description": "The next-generation REST API for managing a Redis Enterprise Cluster" + "title": "Authentication Service REST API", + "description": "REST API for the Authentication Service, primarily used for exposing SSO related endpoints.", + "version": "1.0.0" }, "servers": [ { @@ -11,1656 +11,205 @@ } ], "paths": { - "/v1/migrations/{uid}": { + "/v1/auth/sso/saml/login": { "get": { "x-stability-level": "stable", "x-publish-docs": true, - "summary": "Get migration status of a bdb in the cluster", - "description": "Migration status of a bdb in the cluster", - "operationId": "get_migration", + "summary": "Starts SP-initiated SAML login flow", + "description": "Generates a redirect URL to the IdP for SAML authentication.", + "operationId": "login", "tags": [ - "Migrations" + "Auth" ], - "security": [ - { - "Auth": [ - "view_bdb_info" - ] - } - ], - "parameters": [ - { - "name": "uid", - "in": "path", - "description": "The migration unique ID", - "required": true, - "schema": { - "type": "integer", - "x-go-type": "json.Number" - }, - "example": 1 - } - ], - "responses": { - "200": { - "description": "migration information", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MigrationResponse" - } - } - } - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - } - } - }, - "components": { - "schemas": { - "JWT": { - "required": [ - "token", - "uid" - ], - "properties": { - "token": { - "type": "string", - "description": "Generated JWT" - }, - "uid": { - "type": "string", - "description": "Uid of user" - } - } - }, - "Error": { - "required": [ - "error_code", - "description", - "status_code" - ], - "properties": { - "error_code": { - "type": "string", - "description": "Semantic error code (e.g., password_not_complex)" - }, - "description": { - "type": "string", - "description": "Human-readable error description" - }, - "status_code": { - "type": "integer", - "x-go-json-ignore": true - } - } - }, - "Crdb": { - "type": "object", - "properties": { - "guid": { - "type": "string", - "description": "The GUID of the Active-Active database." - }, - "name": { - "type": "string", - "description": "Name of Active-Active database." - }, - "managed_by": { - "type": "string", - "description": "The component that manages the A-A database." - }, - "encryption": { - "type": "boolean", - "description": "Encrypt communication", - "default": false - }, - "default_db_config": { - "$ref": "#/components/schemas/DatabaseConfig" - }, - "volatile_config_fields": { - "description": "A list of DB config fields that will be set even if unchanged.\nThis list does not persist, and is specific for the API request it\nis part of.\n", - "type": "array", - "items": { - "type": "string" - } - }, - "local_databases": { - "description": "Mapping of instance IDs for local databases to local BDB IDs.", - "type": "array", - "readOnly": true, - "items": { - "type": "object", - "properties": { - "id": { - "$ref": "#/components/schemas/InstanceId" - }, - "bdb_uid": { - "description": "Local cluster Bdatabases UID.", - "type": "string" - } - } - } - }, - "instances": { - "type": "array", - "description": "Active-Active instances.", - "items": { - "$ref": "#/components/schemas/InstanceInfo" - } - }, - "causal_consistency": { - "type": "boolean", - "description": "Enables causal consistency across crdt instances", - "default": false - }, - "featureset_version": { - "type": "integer", - "description": "Active-Active database active FeatureSet version" - }, - "protocol_version": { - "type": "integer", - "description": "Active-Active database active protocol version" - }, - "modules": { - "type": "array", - "description": "CRDB-compatible Redis modules.", - "items": { - "$ref": "#/components/schemas/Module" - } - } - } - }, - "InstanceInfo": { - "description": "Active-Active instance information.", - "type": "object", - "properties": { - "id": { - "$ref": "#/components/schemas/InstanceId" - }, - "compression": { - "type": "integer", - "description": "Compression level when syncing from this source.\n", - "minimum": 0, - "maximum": 6, - "default": 3 - }, - "cluster": { - "$ref": "#/components/schemas/ClusterInfo" - }, - "db_config": { - "$ref": "#/components/schemas/DatabaseConfig" - }, - "db_uid": { - "type": "string", - "description": "ID of local database instance. This field is likely to be\nempty for instances other than the local one.\n" - } - } - }, - "DatabaseConfig": { - "type": "object", - "properties": { - "cert": { - "type": "string", - "description": "Optional PEM-encoded server certificate for the underlying database instance." - }, - "private_key": { - "type": "string", - "description": "Optional PEM-encoded private key matching cert for the underlying database instance." - }, - "replication": { - "type": "boolean", - "description": "Database replication", - "default": true - }, - "rack_aware": { - "type": "boolean", - "description": "Require the database to be always replicated across multiple racks", - "default": false - }, - "memory_size": { - "type": "integer", - "description": "Database memory size limit, in bytes.", - "default": 0 - }, - "data_persistence": { - "description": "Database on-disk persistence", - "type": "string", - "enum": [ - "disabled", - "snapshot", - "aof" - ], - "default": "aof" - }, - "tls_mode": { - "type": "string", - "enum": [ - "disabled", - "replica_ssl", - "enabled" - ], - "default": "disabled", - "description": "Encrypt communication" - }, - "authentication_redis_pass": { - "type": "string", - "description": "Redis AUTH password" - }, - "authentication_admin_pass": { - "type": "string", - "description": "Administrative databases access token" - }, - "port": { - "type": "integer", - "description": "TCP port for database access", - "minimum": 1, - "maximum": 65535 - }, - "shards_count": { - "type": "integer", - "minimum": 1, - "maximum": 512, - "default": 1, - "description": "Number of database shards" - }, - "shard_key_regex": { - "type": "array", - "description": "Custom keyname-based sharding rules. Custom keyname-based sharding rules.\n\nTo use the default rules you should set the value to:\n [ { \\\"regex\\\": \\\".*\\\\{(?.*)\\\\}.*\\\" }, { \\\"regex\\\": \\\"(?.*)\\\" } ]\n", - "items": { - "type": "object", - "properties": { - "regex": { - "type": "string" - } - }, - "required": [ - "regex" - ] - } - }, - "oss_sharding": { - "type": "boolean", - "default": false, - "description": "An alternative to shard_key_regex for using the common case of the oss shard hashing policy" - }, - "oss_cluster": { - "type": "boolean", - "default": false, - "description": "Enables OSS Cluster mode" - }, - "proxy_policy": { - "type": "string", - "enum": [ - "single", - "all-master-shards", - "all-nodes" - ], - "description": "The policy used for proxy binding to the endpoint" - }, - "shards_placement": { - "description": "Control the density of shards: should they reside on as few or as many nodes as possible", - "type": "string", - "enum": [ - "dense", - "sparse" - ] - }, - "oss_cluster_api_preferred_ip_type": { - "type": "string", - "description": "Indicates preferred ip type in oss cluster API: internal/external", - "enum": [ - "internal", - "external" - ] - }, - "bigstore": { - "type": "boolean", - "default": false, - "description": "Database driver is Redis on Flash" - }, - "bigstore_ram_size": { - "type": "integer", - "default": 0, - "description": "Memory size of RAM size" - }, - "aof_policy": { - "type": "string", - "enum": [ - "appendfsync-every-sec", - "appendfsync-always" - ], - "default": "appendfsync-every-sec", - "description": "Policy for Append-Only File data persistence" - }, - "snapshot_policy": { - "type": "array", - "description": "Policy for snapshot-based data persistence.\n\nDataset snapshot will be taken every N secs if there are at least M writes changes in the dataset\n", - "items": { - "type": "object", - "description": "Policy criteria expressed in minimum writes in a given time window (seconds)", - "properties": { - "secs": { - "type": "integer", - "minimum": 1 - }, - "writes": { - "type": "integer", - "minimum": 1 - } - }, - "required": [ - "secs", - "writes" - ] - } - }, - "max_aof_load_time": { - "type": "integer", - "default": 3600, - "description": "Hint for maximum AOF reload time" - }, - "max_aof_file_size": { - "type": "integer", - "default": 322122547200, - "description": "Hint for maximum AOF file size" - } - } - }, - "ClusterInfo": { - "type": "object", - "description": "Configuration details of a cluster that is part of a multi-master\ndatabase.\n", - "properties": { - "name": { - "type": "string", - "description": "Cluster fully qualified name, used to unique identify the cluster.\n\nTypically this is the same as the hostname used in the URL, although\nin some configruations the URL may point to a different name/address.\n" - }, - "url": { - "type": "string", - "description": "Cluster access URL." - }, - "replication_endpoint": { - "type": "string", - "description": "Address to use for peer replication.\n\nIf not specified, it is assumed that standard cluster naming conventions apply.\n" - }, - "replication_tls_sni": { - "type": "string", - "description": "Cluster SNI for TLS connections." - }, - "credentials": { - "type": "object", - "description": "Cluster access credentials.", - "properties": { - "username": { - "type": "string" - }, - "password": { - "type": "string" - } - }, - "required": [ - "username", - "password" - ] - } - } - }, - "Module": { - "type": "object", - "description": "Configuration details of a module that runs in a multi-master\ndatabase.\n", - "properties": { - "module_name": { - "type": "string", - "description": "Module name" - }, - "featureset_version": { - "type": "integer", - "minimum": 0, - "description": "Module featureset version." - } - }, - "required": [ - "module_name", - "featureset_version" - ] - }, - "Task": { - "type": "object", - "description": "An administrative task that gets invoked as a result of a user request.\n", - "properties": { - "id": { - "type": "string", - "readOnly": true - }, - "crdb_guid": { - "type": "string", - "readOnly": true - }, - "started": { - "type": "string", - "format": "date-time", - "example": "2018-03-20T09:12:28Z", - "readOnly": true - }, - "ended": { - "type": "string", - "format": "date-time", - "example": "2018-03-20T09:12:28Z", - "readOnly": true - }, - "worker_name": { - "type": "string", - "readOnly": true, - "description": "The worker that executes the task." - }, - "operation": { - "type": "string", - "readOnly": true, - "description": "The operation that is running." - }, - "status": { - "type": "string", - "readOnly": true, - "description": "Options:\n\nqueued\n\nstarted\n\nfinished\n\nfailed\n" - }, - "progress": { - "type": "object", - "readOnly": true, - "description": "Shows what the task is doing when its status is started", - "properties": { - "worker": { - "type": "string", - "description": "The step the worker is executing" - }, - "clusters": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The instance cluster name" - }, - "progress": { - "type": "string", - "description": "The step the instance coordinator is executing" - } - } - } - } - } - }, - "errors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "cluster_name": { - "type": "string", - "description": "Cluster on which error occurred." - }, - "error_code": { - "type": "string", - "description": "Returned or generated error code." - }, - "description": { - "type": "string", - "description": "Returned or generated error description." - } - } - } - } - } - }, - "ErrorDetails": { - "type": "object", - "description": "Error response details.", - "properties": { - "error_code": { - "type": "string", - "description": "Returned or generated error code." - }, - "description": { - "type": "string", - "description": "Returned or generated error description." - } - } - }, - "InstanceId": { - "type": "integer", - "minimum": 1, - "maximum": 31, - "description": "Unique instance ID." - }, - "Database": { - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "string", - "description": "Unique id of the Database" - }, - "name": { - "type": "string", - "description": "Name of the Database" - } - } - }, - "FeatureFlag": { - "type": "object", - "description": "A configuration object that represents a Feature Flag following OpenFeature specification, which can be used to enable or disable features with variants and targeting rules.", - "properties": { - "state": { - "type": "string", - "description": "The state of the feature flag.", - "enum": [ - "ENABLED", - "DISABLED" - ] - }, - "variants": { - "type": "object", - "description": "A map of variant names to their values. Values can be of any type (boolean, string, number, object).", - "additionalProperties": true - }, - "defaultVariant": { - "type": "string", - "description": "The name of the variant to use as the default when no targeting rules match." - }, - "targeting": { - "type": "object", - "description": "Optional targeting rules that determine which variant to return based on context.", - "x-omitempty": true - }, - "metadata": { - "type": "object", - "description": "Optional metadata associated with the feature flag. Keys are strings, values can be any type.", - "properties": { - "hidden": { - "type": "boolean", - "description": "When true, this flag is hidden from feature flags listings.", - "default": false - } - }, - "additionalProperties": true, - "x-omitempty": true - } - } - }, - "FeatureFlagDefinitionResponse": { - "type": "object", - "description": "A configuration object that represents a Feature Flag following OpenFeature specification, which can be used to enable or disable features with variants and targeting rules.", - "properties": { - "state": { - "type": "string", - "description": "The state of the feature flag.", - "enum": [ - "ENABLED", - "DISABLED" - ] - }, - "variants": { - "type": "object", - "description": "A map of variant names to their values. Values can be of any type (boolean, string, number, object).", - "additionalProperties": true - }, - "defaultVariant": { - "type": "string", - "description": "The name of the variant to use as the default when no targeting rules match." - }, - "targeting": { - "type": "object", - "description": "Optional targeting rules that determine which variant to return based on context.", - "x-omitempty": true - }, - "metadata": { - "type": "object", - "description": "Optional metadata associated with the feature flag. Keys are strings, values can be any type.", - "additionalProperties": true, - "x-omitempty": true - } - } - }, - "FeatureFlagEvaluationResponse": { - "type": "object", - "properties": { - "value": { - "description": "The evaluated value of the feature flag (can be any type)" - }, - "key": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "variant": { - "description": "The variant name that was selected (can be any type)" - }, - "metadata": { - "type": "object", - "additionalProperties": true - } - } - }, - "DatabaseHealthReport": { - "type": "object", - "required": [ - "id", - "name", - "availability", - "high_availability", - "status", - "version", - "creation_time", - "last_configured_time", - "last_backup_time", - "persistence", - "shards_placement", - "endpoints", - "shards", - "active_alerts" - ], - "properties": { - "id": { - "type": "string", - "description": "Database id" - }, - "name": { - "type": "string", - "description": "Database name" - }, - "availability": { - "$ref": "#/components/schemas/replication_status", - "description": "Whether the BDB is available (DMC is connected to all master shards)" - }, - "status": { - "enum": [ - "active", - "active-change-pending", - "pending", - "import-pending", - "delete-pending", - "recovery", - "creation-failed", - "unknown" - ], - "type": "string", - "default": "unknown", - "description": "Database life-cycle status." - }, - "version": { - "type": "string", - "description": "Database version." - }, - "creation_time": { - "type": "string", - "format": "date-time", - "description": "Database creation time." - }, - "last_configured_time": { - "type": "string", - "format": "date-time", - "description": "Database last configuration time." - }, - "last_backup_time": { - "type": "string", - "format": "date-time", - "description": "Database last backup time." - }, - "persistence": { - "type": "string", - "enum": [ - "disabled", - "aof", - "rdb" - ], - "default": "disabled", - "description": "Database persistence type." - }, - "shards_placement": { - "type": "string", - "enum": [ - "dense", - "sparse" - ], - "description": "Database shards placement." - }, - "endpoints": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Endpoint" - }, - "description": "Database endpoints." - }, - "shards": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ShardHealthReport" - }, - "description": "Database shards." - }, - "state_machine": { - "type": "object", - "$ref": "#/components/schemas/StateMachine", - "description": "Currently active state machine for the database" - }, - "active_alerts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Alert" - }, - "description": "List of active alerts for the database" - }, - "high_availability": { - "type": "object", - "$ref": "#/components/schemas/HighAvailability" - } - } - }, - "HighAvailability": { - "type": "object", - "required": [ - "status" - ], - "properties": { - "status": { - "description": "Whether every replica of the BDB is healthy", - "$ref": "#/components/schemas/replication_status" - } - } - }, - "ShardHealthReport": { - "type": "object", - "required": [ - "id", - "role", - "status", - "detailed_status" - ], - "properties": { - "id": { - "type": "string" - }, - "role": { - "type": "string", - "enum": [ - "leader", - "follower" - ], - "description": "shard role can be leader or follower" - }, - "status": { - "type": "string", - "enum": [ - "active", - "inactive", - "trimming" - ], - "description": "shard status can be up or trimming" - }, - "detailed_status": { - "type": "string", - "enum": [ - "ok", - "importing", - "timeout", - "loading", - "busy", - "down", - "trimming", - "unknown" - ], - "description": "shard detailed status" - } - } - }, - "ClusterHealthReport": { - "description": "Cluster health report.", - "type": "object", - "required": [ - "fqdn", - "status", - "license", - "certificates", - "nodes", - "active_alerts" - ], - "properties": { - "fqdn": { - "type": "string", - "description": "Cluster FQDN" - }, - "status": { - "type": "string", - "enum": [ - "quorum", - "quorum loss" - ], - "description": "Cluster status" - }, - "license": { - "$ref": "#/components/schemas/LicenseHealthReport" - }, - "certificates": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Certificate" - }, - "description": "List of certificates in the cluster" - }, - "nodes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Node" - }, - "description": "List of nodes in the cluster" - }, - "active_alerts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Alert" - } - } - } - }, - "LicenseHealthReport": { - "description": "License health report.", - "type": "object", - "required": [ - "expired", - "shards_in_use", - "shards_limit" - ], - "properties": { - "expired": { - "type": "boolean", - "description": "Whether the license has expired" - }, - "shards_in_use": { - "type": "integer", - "description": "Accumulated number of shards in use by databases in the cluster" - }, - "shards_limit": { - "type": "integer", - "description": "Shards limit specified in cluster license" - } - } - }, - "Certificate": { - "description": "Certificate information.", - "type": "object", - "required": [ - "type", - "expired", - "valid_until" - ], - "properties": { - "type": { - "type": "string", - "description": "Certificate type" - }, - "expired": { - "type": "boolean", - "description": "Whether the certificate has expired" - }, - "valid_until": { - "type": "string", - "format": "date-time", - "description": "Certificate expiration time" - } - } - }, - "Node": { - "description": "Node information.", - "type": "object", - "required": [ - "id", - "status", - "role", - "version", - "shards", - "memory", - "observed_at", - "services" - ], - "properties": { - "id": { - "type": "string", - "description": "Node id" - }, - "status": { - "type": "string", - "description": "Node status" - }, - "role": { - "type": "string", - "description": "Node role can be leader or follower", - "enum": [ - "leader", - "follower" - ] - }, - "version": { - "type": "string", - "description": "RS version installed on the node" - }, - "shards": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ShardHealthReport" - }, - "description": "Shards on the node." - }, - "memory": { - "type": "object", - "$ref": "#/components/schemas/Memory", - "description": "Memory information regarding the node" - }, - "observed_at": { - "type": "integer", - "format": "int64", - "description": "Unix time in seconds when the value was last written in the CCS" - }, - "services": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Service" - } - } - } - }, - "Service": { - "description": "Services running on the node managed by supervisor", - "type": "object", - "required": [ - "name", - "status" - ], - "properties": { - "name": { - "type": "string", - "description": "Name of the service" - }, - "status": { - "type": "string", - "description": "Status of the service corresponding to the statename returned by supervisor" - } - } - }, - "Memory": { - "description": "Memory information", - "type": "object", - "required": [ - "total_ram", - "free_ram", - "free_provisional_ram", - "total_provisional_ram", - "overbooking_depth" - ], - "properties": { - "total_ram": { - "type": "integer", - "format": "int64", - "description": "Total ram the node has in bytes" - }, - "free_ram": { - "type": "integer", - "format": "int64", - "description": "Free ram the node has in bytes" - }, - "free_provisional_ram": { - "type": "integer", - "format": "int64", - "description": "Remaining ram for provisioning new shards on the node" - }, - "total_provisional_ram": { - "type": "integer", - "format": "int64", - "description": "Total ram for provisioning shards on the node" - }, - "overbooking_depth": { - "type": "integer", - "format": "int64", - "description": "How much the node is overbooked or has capacity remaining, like free provisional ram but takes into account shards_overbooking (can be negative if it is overbooked)" - } - } - }, - "Alert": { - "description": "Alert information", - "type": "object", - "required": [ - "name", - "active_since" - ], - "properties": { - "name": { - "type": "string", - "description": "Alert name" - }, - "active_since": { - "type": "string", - "format": "date-time", - "description": "Since what time the alert is active" + "parameters": [ + { + "name": "relayState", + "in": "query", + "required": false, + "schema": { + "type": "string" + }, + "description": "An optional relay state to be included in the SAML request." } - } - }, - "Endpoint": { - "description": "Endpoint information", - "type": "object", - "required": [ - "name", - "availability" ], - "properties": { - "name": { - "type": "string", - "description": "Endpoint name" + "responses": { + "200": { + "$ref": "#/components/responses/SamlLoginResponse" }, - "availability": { - "description": "Whether the endpoint is available as reported by Node WD", - "$ref": "#/components/schemas/replication_status" - } - } - }, - "replication_status": { - "description": "The replication link status", - "type": "string", - "enum": [ - "down", - "up" - ] - }, - "StateMachine": { - "description": "State machine information", - "type": "object", - "required": [ - "name", - "state" - ], - "properties": { - "name": { - "type": "string", - "description": "State machine name" + "400": { + "$ref": "#/components/responses/BadRequest" }, - "state": { - "type": "string", - "description": "State machine state" + "500": { + "$ref": "#/components/responses/InternalServerError" } } - }, - "Migration": { - "type": "object", - "description": "Object structure for migration status.", - "properties": { - "status": { - "description": "Sync status of this source.", - "type": "string", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "lag": { - "description": "Lag in milliseconds between source and destination (while synced).", - "type": "integer", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "rdb_size": { - "description": "Number of source bytes.", - "type": "integer", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "rdb_transferred": { - "description": "Number of source bytes transferred.", - "type": "integer", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "run_id": { - "description": "Syncer run id.", - "type": "string", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "flush_counter": { - "description": "How many times syncer had to restart.", - "type": "integer", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "source_shards": { - "type": "array", - "readOnly": true, - "items": { - "$ref": "#/components/schemas/SourceShard" + } + }, + "/v1/auth/sso/saml/callback": { + "post": { + "x-stability-level": "stable", + "x-publish-docs": true, + "summary": "Handles SAML response from IdP", + "description": "Processes the SAML response from the IdP", + "operationId": "callback", + "tags": [ + "Auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "SAMLResponse" + ], + "properties": { + "SAMLResponse": { + "type": "string", + "description": "Base64-encoded SAML response from the IdP." + }, + "TTL": { + "type": "integer", + "x-go-type": "uint32", + "description": "Time-to-live (TTL) of the token in seconds" + } + } + } } - }, - "error": { - "$ref": "#/components/schemas/MigrationError", - "nullable": true, - "readOnly": true, - "x-omitempty": true - } - } - }, - "SourceShard": { - "type": "object", - "description": "Replication shard with its metadata", - "properties": { - "replication_id": { - "description": "Replication id", - "type": "string", - "readOnly": true - }, - "replication_offset": { - "description": "Replication offset", - "type": "integer", - "readOnly": true - } - } - }, - "MigrationError": { - "type": "object", - "description": "Error information for migration operations", - "properties": { - "error_code": { - "description": "Error code identifying the specific error", - "type": "string", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "message": { - "description": "Human-readable error message", - "type": "string", - "nullable": true, - "readOnly": true, - "x-omitempty": true - }, - "timestamp": { - "description": "Timestamp when the error occurred", - "type": "string", - "nullable": true, - "format": "date-time", - "readOnly": true, - "x-omitempty": true - } - } - }, - "MigrationResponse": { - "type": "object", - "description": "Response wrapper for migration endpoint", - "properties": { - "migration": { - "$ref": "#/components/schemas/Migration" - } - } - }, - "RedisAcl": { - "type": "object", - "description": "An API object that represents a Redis ACL definition.", - "required": [ - "uid", - "name", - "acl", - "min_version", - "max_version" - ], - "properties": { - "uid": { - "description": "Redis ACL unique uid.", - "type": "integer", - "x-go-type": "json.Number" - }, - "name": { - "description": "ACL name.", - "type": "string" - }, - "acl": { - "description": "Redis ACL string definition.", - "type": "string" - }, - "min_version": { - "description": "Minimum Redis version for which this ACL is valid.", - "type": "string" - }, - "max_version": { - "description": "Maximum Redis version for which this ACL is valid.", - "type": "string" - }, - "account_id": { - "description": "SM account ID associated with this ACL.", - "type": "integer" - }, - "action_uid": { - "description": "Action uid. If exists - progress can be tracked by the GET /actions/ API", - "type": "string" } }, - "example": { - "uid": 1, - "name": "default", - "acl": "on >allcommands allkeys", - "min_version": "6.2", - "max_version": "9999" - } - }, - "RoleName": { - "type": "string", - "description": "Name of the management role.", - "enum": [ - "none", - "db_viewer", - "cluster_viewer", - "db_member", - "cluster_member", - "user_manager", - "admin" - ] - }, - "RoleBody": { - "type": "object", - "description": "Common role properties shared across role payloads.", - "properties": { - "name": { - "description": "Role's name.", - "type": "string", - "pattern": "^[a-zA-Z0-9_ \\[\\]()@,.;#-]+$" + "responses": { + "200": { + "$ref": "#/components/responses/SamlCallbackResponse" }, - "management": { - "description": "Role's management role.", - "$ref": "#/components/schemas/RoleName" + "400": { + "$ref": "#/components/responses/BadRequest" }, - "account_id": { - "description": "Account ID. Only applicable to account-scoped roles.", - "type": "integer" + "500": { + "$ref": "#/components/responses/InternalServerError" } } - }, - "Role": { - "description": "An API object that represents a Redis Enterprise role.", - "allOf": [ - { - "$ref": "#/components/schemas/RoleBody" - }, - { - "type": "object", - "required": [ - "uid", - "name", - "management" - ], - "properties": { - "uid": { - "description": "Role's unique uid.", - "type": "integer", - "x-go-type": "json.Number" - } - } - } + } + }, + "/v1/auth/sso/saml/logout": { + "get": { + "x-stability-level": "stable", + "x-publish-docs": true, + "summary": "Starts SP-initiated SAML logout flow", + "description": "Generates a redirect URL to the IdP for SAML logout.", + "operationId": "logout", + "tags": [ + "Auth" ], - "example": { - "uid": 1, - "name": "DBA", - "management": "admin" - } - }, - "RoleCreateRequest": { - "description": "Role creation request payload.", - "allOf": [ - { - "$ref": "#/components/schemas/RoleBody" - }, + "security": [ { - "type": "object", - "properties": { - "uid": { - "description": "Optional uid to assign to the role.", - "type": "integer", - "x-go-type": "json.Number" - } - } + "jwtAuth": [] } ], - "example": { - "name": "Support Engineer", - "management": "cluster_viewer" - } - }, - "User": { - "type": "object", - "description": "An API object that represents an Redis Enterprise Cluster user.", - "required": [ - "uid", - "name", - "role", - "role_uids", - "auth_method" - ], - "properties": { - "uid": { - "description": "User's unique uid.", - "type": "integer", - "x-go-type": "json.Number" - }, - "email": { - "description": "User's email. (pattern matching only ascii characters)", - "type": "string" - }, - "password": { - "description": "User's password. Note that it could also be an already-hashed value, in which case 'password_hash_method' parameter is also provided.", - "type": "string" - }, - "name": { - "description": "User's name. (pattern does not allow non ascii and special characters &,<,>,\")", - "type": "string" - }, - "email_alerts": { - "description": "Activate email alerts for a user.", - "type": "boolean", - "default": true - }, - "bdbs_email_alerts": { - "description": "UIDs of databases that user will receive alerts for.", - "type": "array", - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "cluster_email_alerts": { - "description": "Activate cluster email alerts for a user.", - "type": "boolean" - }, - "auth_method": { - "type": "string", - "enum": [ - "regular", - "certificate", - "entraid", - "sso" - ] - }, - "certificate_subject_line": { - "description": "The certificate's subject line as defined by RFC2253 (for certificate based authentication users only)", - "type": "string" - }, - "password_issue_date": { - "description": "The date in which the password was set.", - "type": "string", - "format": "date-time" - }, - "last_login": { - "description": "Timestamp of the user's last login time. This denotes the last time an authentication with the user's credentials was successful.", - "type": "integer", - "format": "int64" - }, - "role": { - "description": "(deprecated) User's role.", - "x-deprecated-reason": "Use role_uids instead", - "deprecated": true, - "allOf": [ - { - "$ref": "#/components/schemas/RoleName" - } - ] - }, - "role_uids": { - "description": "List of role uids associated with the user", - "type": "array", - "items": { - "type": "integer", - "x-go-type": "json.Number" - } + "responses": { + "200": { + "$ref": "#/components/responses/SamlLogoutResponse" }, - "account_id": { - "description": "SM account ID", - "type": "integer" + "400": { + "$ref": "#/components/responses/BadRequest" }, - "action_uid": { - "description": "Action uid. If exists - progress can be tracked by the GET /actions/ API", - "type": "string" + "401": { + "$ref": "#/components/responses/Unauthorized" }, - "status": { - "description": "Status of the user.", - "type": "string", - "enum": [ - "active", - "locked", - "password_expired" - ] + "500": { + "$ref": "#/components/responses/InternalServerError" } - }, - "example": { - "password_issue_date": "2025-03-02T09:43:34Z", - "last_login": 1760618047, - "email": "user@redis.com", - "name": "John Doe", - "email_alerts": true, - "auth_method": "regular", - "role_uids": [ - 1 - ], - "status": "active" } - }, - "UserRequest": { - "type": "object", - "description": "User modification request.", + } + } + }, + "components": { + "securitySchemes": { + "jwtAuth": { + "type": "apiKey", + "in": "header", + "name": "Authorization" + } + }, + "schemas": { + "Error": { + "required": [ + "error_code", + "description", + "status_code" + ], "properties": { - "name": { - "description": "User's name.", - "type": "string", - "pattern": "^[^&<>\"]*$", - "maxLength": 255, - "minLength": 1 - }, - "email": { - "description": "User's email.", + "error_code": { "type": "string", - "format": "email" - }, - "password": { - "description": "User's password for regular authentication. Required for regular auth method.", - "type": "string" - }, - "email_alerts": { - "description": "Activate email alerts for a user.", - "type": "boolean" - }, - "bdbs_email_alerts": { - "description": "UIDs of databases that user will receive alerts for.", - "type": "array", - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "cluster_email_alerts": { - "description": "Activate cluster email alerts for a user.", - "type": "boolean" + "description": "Semantic error code" }, - "auth_method": { + "description": { "type": "string", - "enum": [ - "regular", - "certificate", - "entraid", - "sso" - ] - }, - "certificate_subject_line": { - "description": "The certificate's subject line as defined by RFC2253 (for certificate based authentication users only)", - "type": "string" - }, - "role": { - "description": "(deprecated) User's role.", - "x-deprecated-reason": "Use role_uids instead", - "x-sunset": "2027-12-31", - "deprecated": true, - "allOf": [ - { - "$ref": "#/components/schemas/RoleName" - } - ] - }, - "role_uids": { - "description": "List of role uids associated with the user", - "type": "array", - "uniqueItems": true, - "minItems": 1, - "items": { - "type": "integer", - "x-go-type": "json.Number" - } - }, - "account_id": { - "description": "SM account ID", - "type": "integer" - }, - "password_hash_method": { - "$ref": "#/components/schemas/PasswordHashMethod" - } - } - }, - "PasswordHashMethod": { - "type": "integer", - "description": "Used when password is passed pre-hashed", - "enum": [ - 1 - ], - "x-enum-varnames": [ - "PreHashed" - ] - }, - "Permissions": { - "type": "object", - "description": "API and UI permissions for a role", - "properties": { - "api_permissions": { - "type": "array", - "description": "List of permission strings", - "items": { - "type": "string" - } - }, - "ui_permissions": { - "type": "array", - "description": "List of permission strings", - "items": { - "type": "string" - } - } - }, - "example": { - "api_permissions": [ - "create_node", - "update_node", - "delete_node" - ], - "ui_permissions": [ - "view_cluster_page", - "view_database_page" - ] - } - }, - "RolesWithPermissions": { - "type": "object", - "description": "A map of role names to their permissions", - "additionalProperties": { - "$ref": "#/components/schemas/Permissions" - }, - "example": { - "admin": { - "api_permissions": [ - "create_node", - "update_node", - "delete_node" - ], - "ui_permissions": [ - "view_cluster_page", - "view_database_page" - ] + "description": "Human-readable error description" }, - "db_viewer": { - "api_permissions": [ - "view_bdb_info", - "view_all_bdbs_info" - ], - "ui_permissions": [ - "view_database_page" - ] + "status_code": { + "type": "integer", + "x-go-json-ignore": true } } } }, "responses": { - "BadRequest": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "NotFound": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "Unauthorized": { - "description": "Unauthorized", + "SamlLoginResponse": { + "description": "Successful response containing the redirect URL.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "type": "object", + "properties": { + "redirectUrl": { + "type": "string", + "description": "The URL to redirect the user to for SAML authentication." + } + } } } } }, - "Forbidden": { - "description": "Forbidden", + "SamlCallbackResponse": { + "description": "Successful response after processing a SAML response.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "type": "object", + "properties": { + "access_token": { + "type": "string", + "description": "JWT access token for the authenticated user" + }, + "uid": { + "type": "string", + "description": "Unique identifier for the authenticated user" + } + } } } } }, - "InternalServerError": { - "description": "Internal Server Error", + "SamlLogoutResponse": { + "description": "Successful response containing the redirect URL.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "type": "object", + "properties": { + "redirectUrl": { + "type": "string", + "description": "The URL to redirect the user to for SAML logout." + } + } } } } }, - "ServiceUnavailable": { - "description": "Service Unavailable", + "BadRequest": { + "description": "Bad request", "content": { "application/json": { "schema": { @@ -1669,8 +218,8 @@ } } }, - "NotAcceptable": { - "description": "Not Acceptable", + "Unauthorized": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -1679,8 +228,8 @@ } } }, - "Conflict": { - "description": "Conflict", + "InternalServerError": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -1689,13 +238,6 @@ } } } - }, - "securitySchemes": { - "Auth": { - "type": "apiKey", - "in": "header", - "name": "r-auth-user" - } } } } \ No newline at end of file