Fix OpenAPI 3.0 validation errors in openapi.json #83

Merged
vitalif merged 5 commits from epicstyt/vitastor:openapi-lint into master 2026-09-02 20:10:02 +03:00

View File

@@ -1,6 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"title": "Vitastor control API",
"description": "Vitastor control API",
"version": "3.0.2",
"license": {
@@ -11,10 +12,9 @@
"/status": { "get": {
"summary": "Show server status",
"operationId": "status",
"produces": [ "application/json" ],
"parameters": [],
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "Cluster status", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"pool_count": { "type": "integer", "format": "uint64", "description": "Total number of pools" },
@@ -60,7 +60,6 @@
"/image/list": { "get": {
"summary": "List images",
"operationId": "imageListGet",
"produces": [ "application/json" ],
"parameters": [ {
"name": "params",
"in": "query",
@@ -69,23 +68,19 @@
"explode": true
} ],
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageList" } } } }
"200": { "description": "List of images", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageList" } } } }
}
}, "post": {
"summary": "List images",
"operationId": "imageListPost",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageListParams" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageList" } } } }
"200": { "description": "List of images", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageList" } } } }
}
} },
"/image/create": { "post": {
"summary": "Create an image, snapshot, or a clone",
"operationId": "imageCreate",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"required": [ "image" ],
@@ -113,7 +108,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Image" } } } },
"200": { "description": "The created image, snapshot or clone", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Image" } } } },
"400": { "$ref": "#/components/responses/Invalid" },
"403": { "$ref": "#/components/responses/Forbidden" },
"409": { "$ref": "#/components/responses/UpdateConflict" },
@@ -123,8 +118,6 @@
"/image/modify": { "post": {
"summary": "Modify an image",
"operationId": "imageModify",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"required": [ "image" ],
@@ -154,7 +147,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Image" } } } },
"200": { "description": "The modified image", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Image" } } } },
"400": { "$ref": "#/components/responses/Invalid" },
"403": { "$ref": "#/components/responses/Forbidden" },
"409": { "$ref": "#/components/responses/UpdateConflict" },
@@ -164,8 +157,6 @@
"/image/delete": { "post": {
"summary": "Delete image(s)",
"operationId": "imageDelete",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"oneOf": [ {
"type": "object",
@@ -195,7 +186,7 @@
} ]
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "Deleted and rebased images", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"deleted_ids": { "type": "array", "items": { "type": "integer", "format": "uint64" }, "description": "Full inode ID(s) of deleted images" },
@@ -214,17 +205,15 @@
"/image/flatten": { "post": {
"summary": "Flatten an image",
"operationId": "imageFlatten",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"required": [ "names" ],
"required": [ "image" ],
"properties": {
"image": { "type": "string", "description": "Image name to flatten" }
}
} } } },
"responses": {
"200": { "content": { "text/plain": { "schema": { "type": "string", "description": "Empty response" } } } },
"200": { "description": "Image flattened", "content": { "text/plain": { "schema": { "type": "string", "description": "Empty response" } } } },
"400": { "$ref": "#/components/responses/Invalid" },
"403": { "$ref": "#/components/responses/Forbidden" },
"409": { "$ref": "#/components/responses/UpdateConflict" },
@@ -234,7 +223,6 @@
"/osd/list": { "get": {
"summary": "List OSDs",
"operationId": "osdListGet",
"produces": [ "application/json" ],
"parameters": [ {
"name": "params",
"in": "query",
@@ -243,24 +231,21 @@
"explode": true
} ],
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OsdList" } } } }
"200": { "description": "List of OSDs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OsdList" } } } }
}
}, "post": {
"summary": "List OSDs",
"operationId": "osdListPost",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OsdListParams" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OsdList" } } } }
"200": { "description": "List of OSDs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OsdList" } } } }
}
} },
"/osd/alloc": { "post": {
"summary": "Allocate a new OSD number",
"operationId": "osdAlloc",
"produces": [ "application/json" ],
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "The allocated OSD number", "content": { "application/json": { "schema": {
"type": "integer",
"format": "uint64",
"description": "New OSD number"
@@ -272,8 +257,6 @@
"/osd/delete": { "post": {
"summary": "Delete stopped OSD(s) from etcd",
"operationId": "osdDelete",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -283,7 +266,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "Deleted OSD numbers", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"deleted_osds": {
@@ -291,13 +274,11 @@
"items": { "type": "integer", "format": "uint64" },
"description": "Deleted OSD numbers"
}
},
"format": "uint64",
"description": "New OSD number"
}
} } } },
"400": { "$ref": "#/components/responses/Invalid" },
"409": { "$ref": "#/components/responses/UpdateConflict" },
"412": { "content": { "application/json": { "schema": {
"412": { "description": "Precondition failed: removing these OSD(s) would affect some pools", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"pool_effects": {
@@ -322,8 +303,6 @@
"/osd/modify": { "post": {
"summary": "Modify OSD reweight, tags or noout flag",
"operationId": "osdModify",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -334,15 +313,13 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "OSD settings after modification", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"reweight": { "type": "number", "minimum": 0, "maximum": 1, "description": "OSD weight" },
"tags": { "type": "array", "items": { "type": "string" }, "description": "OSD tags" },
"noout": { "type": "boolean", "description": "noout flag" }
},
"format": "uint64",
"description": "New OSD number"
}
} } } },
"400": { "$ref": "#/components/responses/Invalid" },
"409": { "$ref": "#/components/responses/UpdateConflict" },
@@ -352,7 +329,6 @@
"/pool/list": { "get": {
"summary": "List pools",
"operationId": "poolListGet",
"produces": [ "application/json" ],
"parameters": [ {
"name": "params",
"in": "query",
@@ -361,23 +337,19 @@
"explode": true
} ],
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PoolList" } } } }
"200": { "description": "List of pools", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PoolList" } } } }
}
}, "post": {
"summary": "List pools",
"operationId": "poolListPost",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PoolListParams" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PoolList" } } } }
"200": { "description": "List of pools", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PoolList" } } } }
}
} },
"/pool/create": { "post": {
"summary": "Create a pool",
"operationId": "poolCreate",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"allOf": [ {
"$ref": "#/components/schemas/PoolConfig"
@@ -387,7 +359,7 @@
} } ]
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "The created pool", "content": { "application/json": { "schema": {
"$ref": "#/components/schemas/PoolConfig"
} } } },
"400": { "$ref": "#/components/responses/Invalid" },
@@ -398,8 +370,6 @@
"/pool/modify": { "post": {
"summary": "Modify a pool",
"operationId": "poolModify",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"allOf": [ {
"$ref": "#/components/schemas/PoolConfig"
@@ -410,7 +380,7 @@
} } ]
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "The modified pool", "content": { "application/json": { "schema": {
"$ref": "#/components/schemas/PoolConfig"
} } } },
"400": { "$ref": "#/components/responses/Invalid" },
@@ -421,8 +391,6 @@
"/pool/delete": { "post": {
"summary": "Delete a pool",
"operationId": "poolDelete",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -432,7 +400,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "Pool deleted", "content": { "application/json": { "schema": {
"type": "object",
"properties": { "ok": { "type": "boolean" } }
} } } },
@@ -444,7 +412,6 @@
"/user/list": { "get": {
"summary": "List users",
"operationId": "userListGet",
"produces": [ "application/json" ],
"parameters": [ {
"name": "params",
"in": "query",
@@ -453,26 +420,22 @@
"explode": true
} ],
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserList" } } } }
"200": { "description": "List of users", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserList" } } } }
}
}, "post": {
"summary": "List users",
"operationId": "userListPost",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserListParams" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserList" } } } }
"200": { "description": "List of users", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserList" } } } }
}
} },
"/user/modify": { "post": {
"summary": "Modify a user",
"operationId": "userModify",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "The modified user", "content": { "application/json": { "schema": {
"$ref": "#/components/schemas/User"
} } } },
"400": { "$ref": "#/components/responses/Invalid" },
@@ -483,8 +446,6 @@
"/user/delete": { "post": {
"summary": "Delete a user",
"operationId": "userDelete",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -492,7 +453,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "User deleted", "content": { "application/json": { "schema": {
"type": "object",
"properties": { "ok": { "type": "boolean" } }
} } } },
@@ -504,7 +465,6 @@
"/pg/list": { "get": {
"summary": "List PGs",
"operationId": "pgListGet",
"produces": [ "application/json" ],
"parameters": [ {
"name": "params",
"in": "query",
@@ -513,23 +473,19 @@
"explode": true
} ],
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PgList" } } } }
"200": { "description": "List of PGs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PgList" } } } }
}
}, "post": {
"summary": "List PGs",
"operationId": "pgListPost",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PgListParams" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PgList" } } } }
"200": { "description": "List of PGs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PgList" } } } }
}
} },
"/data/delete": { "post": {
"summary": "Remove inode data without changing metadata",
"operationId": "dataDelete",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -540,14 +496,14 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "Number of removed objects", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"removed_objects": { "type": "integer", "format": "uint64", "description": "Removed object count" }
}
} } } },
"400": { "$ref": "#/components/responses/Invalid" },
"412": { "content": { "application/json": { "schema": {
"412": { "description": "Precondition failed: some data could not be removed", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"total_objects": { "type": "integer", "format": "uint64", "description": "Total object count" },
@@ -570,7 +526,6 @@
"/data/describe": { "get": {
"summary": "Describe unclean object locations in the cluster",
"operationId": "dataDescribeGet",
"produces": [ "application/json" ],
"parameters": [ {
"name": "params",
"in": "query",
@@ -579,23 +534,19 @@
"explode": true
} ],
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DataDescribe" } } } }
"200": { "description": "Unclean object locations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DataDescribe" } } } }
}
}, "post": {
"summary": "Describe unclean object locations in the cluster",
"operationId": "dataDescribePost",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DataDescribeParams" } } } },
"responses": {
"200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DataDescribe" } } } }
"200": { "description": "Unclean object locations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DataDescribe" } } } }
}
} },
"/data/fix": { "post": {
"summary": "Fix inconsistent objects in the cluster by deleting some copies",
"operationId": "dataFix",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -619,7 +570,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "The removed object copy", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"inode": { "type": "integer", "format": "uint64", "description": "Full inode ID with pool" },
@@ -634,8 +585,6 @@
"/data/merge": { "post": {
"summary": "Merge layer data without changing metadata",
"operationId": "dataMerge",
"consumes": [ "application/json" ],
"produces": [ "application/json" ],
"requestBody": { "content": { "application/json": { "schema": {
"type": "object",
"properties": {
@@ -648,7 +597,7 @@
}
} } } },
"responses": {
"200": { "content": { "application/json": { "schema": {
"200": { "description": "The merged layer range", "content": { "application/json": { "schema": {
"type": "object",
"properties": {
"from": { "type": "string", "description": "First merged parent layer" },