mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-31 17:28:13 +00:00
openapi: work around issue for flattenned untagged enum (fix #1249)
This commit is contained in:
@@ -103,7 +103,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/AddBucketAliasRequest"
|
"$ref": "#/components/schemas/BucketAliasEnum"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1409,7 +1409,7 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/RemoveBucketAliasRequest"
|
"$ref": "#/components/schemas/BucketAliasEnum"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1722,24 +1722,6 @@
|
|||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"AddBucketAliasRequest": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/BucketAliasEnum"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"bucketId"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"bucketId": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"AddBucketAliasResponse": {
|
"AddBucketAliasResponse": {
|
||||||
"$ref": "#/components/schemas/GetBucketInfoResponse"
|
"$ref": "#/components/schemas/GetBucketInfoResponse"
|
||||||
},
|
},
|
||||||
@@ -1957,9 +1939,13 @@
|
|||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
"bucketId",
|
||||||
"globalAlias"
|
"globalAlias"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"bucketId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"globalAlias": {
|
"globalAlias": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -1968,6 +1954,7 @@
|
|||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
"bucketId",
|
||||||
"localAlias",
|
"localAlias",
|
||||||
"accessKeyId"
|
"accessKeyId"
|
||||||
],
|
],
|
||||||
@@ -1975,6 +1962,9 @@
|
|||||||
"accessKeyId": {
|
"accessKeyId": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"bucketId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"localAlias": {
|
"localAlias": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -3912,6 +3902,46 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"NodeRoleChangeRequest": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"remove"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the node for which this change applies"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set `remove` to `true` to remove the node from the layout"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/NodeAssignedRole"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the node for which this change applies"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"NodeUpdateTrackers": {
|
"NodeUpdateTrackers": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -3973,24 +4003,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"RemoveBucketAliasRequest": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/schemas/BucketAliasEnum"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"bucketId"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"bucketId": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"RemoveBucketAliasResponse": {
|
"RemoveBucketAliasResponse": {
|
||||||
"$ref": "#/components/schemas/GetBucketInfoResponse"
|
"$ref": "#/components/schemas/GetBucketInfoResponse"
|
||||||
},
|
},
|
||||||
@@ -4180,7 +4192,7 @@
|
|||||||
"roles": {
|
"roles": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/components/schemas/NodeRoleChange"
|
"$ref": "#/components/schemas/NodeRoleChangeRequest"
|
||||||
},
|
},
|
||||||
"description": "New node roles to assign or remove in the cluster layout"
|
"description": "New node roles to assign or remove in the cluster layout"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use utoipa::{Modify, OpenApi};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use utoipa::{Modify, OpenApi, ToSchema};
|
||||||
|
|
||||||
use crate::api::*;
|
use crate::api::*;
|
||||||
|
|
||||||
@@ -246,7 +247,7 @@ For example to declare 100GB, you must set `capacity: 100000000000`.
|
|||||||
Garage uses internally the International System of Units (SI), it assumes that 1kB = 1000 bytes, and displays storage as kB, MB, GB (and not KiB, MiB, GiB that assume 1KiB = 1024 bytes).
|
Garage uses internally the International System of Units (SI), it assumes that 1kB = 1000 bytes, and displays storage as kB, MB, GB (and not KiB, MiB, GiB that assume 1KiB = 1024 bytes).
|
||||||
",
|
",
|
||||||
request_body(
|
request_body(
|
||||||
content=UpdateClusterLayoutRequest,
|
content=UpdateClusterLayoutRequestOpenapi,
|
||||||
description="
|
description="
|
||||||
To add a new node to the layout or to change the configuration of an existing node, simply set the values you want (`zone`, `capacity`, and `tags`).
|
To add a new node to the layout or to change the configuration of an existing node, simply set the values you want (`zone`, `capacity`, and `tags`).
|
||||||
To remove a node, simply pass the `remove: true` field.
|
To remove a node, simply pass the `remove: true` field.
|
||||||
@@ -262,6 +263,45 @@ Contrary to the CLI that may update only a subset of the fields capacity, zone a
|
|||||||
)]
|
)]
|
||||||
fn UpdateClusterLayout() -> () {}
|
fn UpdateClusterLayout() -> () {}
|
||||||
|
|
||||||
|
// Hack: we cannot use the UpdateClusterLayoutRequest from api.rs,
|
||||||
|
// as it contains (via NodeRoleChange) an untagged enum flattenned into
|
||||||
|
// a struct, which breaks the openapi generator.
|
||||||
|
// See issue #1249.
|
||||||
|
// Instead, we use a rewritten version of the NodeRoleChange struct where
|
||||||
|
// the struct fields are distributed into the enum variants (this is an equivalent
|
||||||
|
// representation, but this way we avoid having to rewrite all uses of the original
|
||||||
|
// struct in the Garage codebase).
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
#[schema(as = UpdateClusterLayoutRequest)]
|
||||||
|
pub struct UpdateClusterLayoutRequestOpenapi {
|
||||||
|
/// New node roles to assign or remove in the cluster layout
|
||||||
|
#[serde(default)]
|
||||||
|
pub roles: Vec<NodeRoleChangeOpenapi>,
|
||||||
|
/// New layout computation parameters to use
|
||||||
|
#[serde(default)]
|
||||||
|
pub parameters: Option<LayoutParameters>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
#[schema(as = NodeRoleChangeRequest)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum NodeRoleChangeOpenapi {
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
Remove {
|
||||||
|
/// ID of the node for which this change applies
|
||||||
|
id: String,
|
||||||
|
/// Set `remove` to `true` to remove the node from the layout
|
||||||
|
remove: bool,
|
||||||
|
},
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
Update {
|
||||||
|
/// ID of the node for which this change applies
|
||||||
|
id: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
role: NodeAssignedRole,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[utoipa::path(post,
|
#[utoipa::path(post,
|
||||||
path = "/v2/PreviewClusterLayoutChanges",
|
path = "/v2/PreviewClusterLayoutChanges",
|
||||||
tag = "Cluster layout",
|
tag = "Cluster layout",
|
||||||
@@ -586,7 +626,7 @@ fn DenyBucketKey() -> () {}
|
|||||||
path = "/v2/AddBucketAlias",
|
path = "/v2/AddBucketAlias",
|
||||||
tag = "Bucket alias",
|
tag = "Bucket alias",
|
||||||
description = "Add an alias for the target bucket. This can be either a global or a local alias, depending on which fields are specified.",
|
description = "Add an alias for the target bucket. This can be either a global or a local alias, depending on which fields are specified.",
|
||||||
request_body = AddBucketAliasRequest,
|
request_body = BucketAliasEnumOpenapi,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Returns exhaustive information about the bucket", body = AddBucketAliasResponse),
|
(status = 200, description = "Returns exhaustive information about the bucket", body = AddBucketAliasResponse),
|
||||||
(status = 500, description = "Internal server error")
|
(status = 500, description = "Internal server error")
|
||||||
@@ -598,7 +638,7 @@ fn AddBucketAlias() -> () {}
|
|||||||
path = "/v2/RemoveBucketAlias",
|
path = "/v2/RemoveBucketAlias",
|
||||||
tag = "Bucket alias",
|
tag = "Bucket alias",
|
||||||
description = "Remove an alias for the target bucket. This can be either a global or a local alias, depending on which fields are specified.",
|
description = "Remove an alias for the target bucket. This can be either a global or a local alias, depending on which fields are specified.",
|
||||||
request_body = RemoveBucketAliasRequest,
|
request_body = BucketAliasEnumOpenapi,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Returns exhaustive information about the bucket", body = RemoveBucketAliasResponse),
|
(status = 200, description = "Returns exhaustive information about the bucket", body = RemoveBucketAliasResponse),
|
||||||
(status = 500, description = "Internal server error")
|
(status = 500, description = "Internal server error")
|
||||||
@@ -606,6 +646,24 @@ fn AddBucketAlias() -> () {}
|
|||||||
)]
|
)]
|
||||||
fn RemoveBucketAlias() -> () {}
|
fn RemoveBucketAlias() -> () {}
|
||||||
|
|
||||||
|
// Hack for issue #1249 (see UpdateClusterLayout)
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
#[schema(as = BucketAliasEnum)]
|
||||||
|
pub enum BucketAliasEnumOpenapi {
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
Global {
|
||||||
|
bucket_id: String,
|
||||||
|
global_alias: String,
|
||||||
|
},
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
Local {
|
||||||
|
bucket_id: String,
|
||||||
|
local_alias: String,
|
||||||
|
access_key_id: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// Node operations
|
// Node operations
|
||||||
// **********************************************
|
// **********************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user