From 5ca633c54b62a98766bab7f69fcd6583e9c3d74b Mon Sep 17 00:00:00 2001 From: karencfv Date: Thu, 29 Aug 2024 20:31:20 +1200 Subject: [PATCH 01/14] skeleton --- clickhouse-admin/api/src/lib.rs | 37 +++++++++++++- clickhouse-admin/src/clickward.rs | 40 ++++++++++++++- clickhouse-admin/src/http_entrypoints.rs | 13 ++++- openapi/clickhouse-admin.json | 62 +++++++++++++++++++++++- 4 files changed, 145 insertions(+), 7 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index 9a011d4387..f1a3e742de 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,7 +2,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use dropshot::{HttpError, HttpResponseOk, RequestContext}; +use dropshot::{HttpError, HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::net::SocketAddrV6; @@ -11,7 +11,7 @@ use std::net::SocketAddrV6; pub trait ClickhouseAdminApi { type Context; - /// Retrieve the address the ClickHouse server or keeper node is listening on + /// Retrieve the address the ClickHouse server or keeper node is listening on. #[endpoint { method = GET, path = "/node/address", @@ -19,6 +19,18 @@ pub trait ClickhouseAdminApi { async fn clickhouse_address( rqctx: RequestContext, ) -> Result, HttpError>; + + /// Generate a ClickHouse configuration file for a server node on a specified + /// directory. + #[endpoint { + method = POST, + // TODO: I'm not sure about this endpoint, could be better? + path = "/server-node/generate-config", + }] + async fn generate_server_config( + rqctx: RequestContext, + body: TypedBody, + ) -> Result, HttpError>; } #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] @@ -26,3 +38,24 @@ pub trait ClickhouseAdminApi { pub struct ClickhouseAddress { pub clickhouse_address: SocketAddrV6, } + +// TODO: Perhaps change this response type for something better +// like an object with all the settings or something like that +/// Success response for server node configuration file generation +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct ServerConfigGenerateResponse { + pub success: bool, +} + +impl ServerConfigGenerateResponse { + pub fn success() -> Self { + Self { success: true } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct ServerSettings { + pub node_id: u64, +} \ No newline at end of file diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index 114201e44b..7b8217e802 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -2,11 +2,15 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use clickhouse_admin_api::ClickhouseAddress; +use camino::Utf8PathBuf; +use clickhouse_admin_api::{ClickhouseAddress, ServerConfigGenerateResponse, ServerSettings}; +use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; +use clickhouse_admin_types::config::{KeeperNodeConfig, ServerNodeConfig}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; use std::io; -use std::net::SocketAddrV6; +use std::net::{SocketAddrV6, Ipv6Addr}; +use std::str::FromStr; #[derive(Debug, thiserror::Error, SlogInlineError)] pub enum ClickwardError { @@ -35,6 +39,7 @@ impl From for HttpError { #[derive(Debug)] pub struct Clickward { + // TODO: Remove address? clickhouse_address: SocketAddrV6, } @@ -43,9 +48,40 @@ impl Clickward { Self { clickhouse_address } } + // TODO: Remove this endpoint? pub fn clickhouse_address( &self, ) -> Result { Ok(ClickhouseAddress { clickhouse_address: self.clickhouse_address }) } + + pub fn generate_server_config( + &self, + settings: ServerSettings, + ) -> Result { + // TODO: This should be part of the request body + let keepers = vec![ + KeeperNodeConfig::new("ff::01".to_string()), + KeeperNodeConfig::new("127.0.0.1".to_string()), + KeeperNodeConfig::new("we.dont.want.brackets.com".to_string()), + ]; + + let servers = vec![ + ServerNodeConfig::new("ff::08".to_string()), + ServerNodeConfig::new("ff::09".to_string()), + ]; + + let config = ClickhouseServerConfig::new( + Utf8PathBuf::from_str("./").unwrap(), + ServerId(settings.node_id), + Utf8PathBuf::from_str("./").unwrap(), + Ipv6Addr::from_str("ff::08").unwrap(), + keepers, + servers, + ); + + config.generate_xml_file().unwrap(); + + Ok(ServerConfigGenerateResponse::success()) + } } diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 05988a73b0..009ad9dbfc 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,8 +5,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use dropshot::HttpError; -use dropshot::HttpResponseOk; -use dropshot::RequestContext; +use dropshot::{HttpResponseOk, HttpResponseCreated, RequestContext, TypedBody}; use std::sync::Arc; type ClickhouseApiDescription = dropshot::ApiDescription>; @@ -28,4 +27,14 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { let output = ctx.clickward().clickhouse_address()?; Ok(HttpResponseOk(output)) } + + async fn generate_server_config( + rqctx: RequestContext, + body: TypedBody, + ) -> Result, HttpError> { + let ctx = rqctx.context(); + let server_settings = body.into_inner(); + let output = ctx.clickward().generate_server_config(server_settings)?; + Ok(HttpResponseCreated(output)) + } } diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index 6bb5367712..bcc98da6cb 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -12,7 +12,7 @@ "paths": { "/node/address": { "get": { - "summary": "Retrieve the address the ClickHouse server or keeper node is listening on", + "summary": "Retrieve the address the ClickHouse server or keeper node is listening on.", "operationId": "clickhouse_address", "responses": { "200": { @@ -33,6 +33,41 @@ } } } + }, + "/server-node/generate-config": { + "post": { + "summary": "Generate a ClickHouse configuration file for a server node on a specified", + "description": "directory.", + "operationId": "generate_server_config", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServerSettings" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "successful creation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServerConfigGenerateResponse" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } } }, "components": { @@ -66,6 +101,31 @@ "message", "request_id" ] + }, + "ServerConfigGenerateResponse": { + "description": "Success response for server node configuration file generation", + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ] + }, + "ServerSettings": { + "type": "object", + "properties": { + "node_id": { + "type": "integer", + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "node_id" + ] } }, "responses": { From 5888f23230f136401917e520f0414f682c4b396b Mon Sep 17 00:00:00 2001 From: karencfv Date: Thu, 29 Aug 2024 20:35:08 +1200 Subject: [PATCH 02/14] fmt --- clickhouse-admin/api/src/lib.rs | 6 ++++-- clickhouse-admin/src/clickward.rs | 10 ++++++---- clickhouse-admin/src/http_entrypoints.rs | 7 +++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index f1a3e742de..b298a47afd 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,7 +2,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use dropshot::{HttpError, HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody}; +use dropshot::{ + HttpError, HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, +}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::net::SocketAddrV6; @@ -58,4 +60,4 @@ impl ServerConfigGenerateResponse { #[serde(rename_all = "snake_case")] pub struct ServerSettings { pub node_id: u64, -} \ No newline at end of file +} diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index 7b8217e802..ab185967e0 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -3,13 +3,15 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use camino::Utf8PathBuf; -use clickhouse_admin_api::{ClickhouseAddress, ServerConfigGenerateResponse, ServerSettings}; -use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; +use clickhouse_admin_api::{ + ClickhouseAddress, ServerConfigGenerateResponse, ServerSettings, +}; use clickhouse_admin_types::config::{KeeperNodeConfig, ServerNodeConfig}; +use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; use std::io; -use std::net::{SocketAddrV6, Ipv6Addr}; +use std::net::{Ipv6Addr, SocketAddrV6}; use std::str::FromStr; #[derive(Debug, thiserror::Error, SlogInlineError)] @@ -81,7 +83,7 @@ impl Clickward { ); config.generate_xml_file().unwrap(); - + Ok(ServerConfigGenerateResponse::success()) } } diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 009ad9dbfc..31f66aa355 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,7 +5,9 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use dropshot::HttpError; -use dropshot::{HttpResponseOk, HttpResponseCreated, RequestContext, TypedBody}; +use dropshot::{ + HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, +}; use std::sync::Arc; type ClickhouseApiDescription = dropshot::ApiDescription>; @@ -31,7 +33,8 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { async fn generate_server_config( rqctx: RequestContext, body: TypedBody, - ) -> Result, HttpError> { + ) -> Result, HttpError> + { let ctx = rqctx.context(); let server_settings = body.into_inner(); let output = ctx.clickward().generate_server_config(server_settings)?; From 14fe73e407a353d4d699d15efa355c595bccab23 Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 30 Aug 2024 14:05:15 +1200 Subject: [PATCH 03/14] stronger types --- Cargo.lock | 1 + clickhouse-admin/api/Cargo.toml | 1 + clickhouse-admin/api/src/lib.rs | 11 ++- clickhouse-admin/src/clickward.rs | 36 ++++++--- clickhouse-admin/types/src/config.rs | 24 ++++-- clickhouse-admin/types/src/lib.rs | 22 ++++-- .../types/testutils/replica-server-config.xml | 2 +- openapi/clickhouse-admin.json | 73 ++++++++++++++++++- 8 files changed, 139 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 923693276a..8666963ed8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,6 +1119,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "clickhouse-admin-api" version = "0.1.0" dependencies = [ + "clickhouse-admin-types", "dropshot 0.10.2-dev", "omicron-common", "omicron-uuid-kinds", diff --git a/clickhouse-admin/api/Cargo.toml b/clickhouse-admin/api/Cargo.toml index ceec09f6c8..a5d1dca202 100644 --- a/clickhouse-admin/api/Cargo.toml +++ b/clickhouse-admin/api/Cargo.toml @@ -8,6 +8,7 @@ license = "MPL-2.0" workspace = true [dependencies] +clickhouse-admin-types.workspace = true dropshot.workspace = true omicron-common.workspace = true omicron-uuid-kinds.workspace = true diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index b298a47afd..b86e5627a4 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,12 +2,13 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. +use clickhouse_admin_types::config::ClickhouseHost; use dropshot::{ HttpError, HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::net::SocketAddrV6; +use std::net::{Ipv6Addr, SocketAddrV6}; #[dropshot::api_description] pub trait ClickhouseAdminApi { @@ -26,8 +27,7 @@ pub trait ClickhouseAdminApi { /// directory. #[endpoint { method = POST, - // TODO: I'm not sure about this endpoint, could be better? - path = "/server-node/generate-config", + path = "/node/server/generate-config", }] async fn generate_server_config( rqctx: RequestContext, @@ -60,4 +60,9 @@ impl ServerConfigGenerateResponse { #[serde(rename_all = "snake_case")] pub struct ServerSettings { pub node_id: u64, + pub keepers: Vec, + pub remote_servers: Vec, + pub config_dir: String, + pub datastore_path: String, + pub listen_addr: Ipv6Addr, } diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index ab185967e0..ad83eda208 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -11,7 +11,7 @@ use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; use std::io; -use std::net::{Ipv6Addr, SocketAddrV6}; +use std::net::SocketAddrV6; use std::str::FromStr; #[derive(Debug, thiserror::Error, SlogInlineError)] @@ -62,24 +62,36 @@ impl Clickward { settings: ServerSettings, ) -> Result { // TODO: This should be part of the request body - let keepers = vec![ - KeeperNodeConfig::new("ff::01".to_string()), - KeeperNodeConfig::new("127.0.0.1".to_string()), - KeeperNodeConfig::new("we.dont.want.brackets.com".to_string()), - ]; + // let keepers = vec![ + // KeeperNodeConfig::new("ff::01".to_string()), + // KeeperNodeConfig::new("127.0.0.1".to_string()), + // KeeperNodeConfig::new("we.dont.want.brackets.com".to_string()), + // ]; - let servers = vec![ - ServerNodeConfig::new("ff::08".to_string()), - ServerNodeConfig::new("ff::09".to_string()), - ]; + // let servers = vec![ + // ServerNodeConfig::new("ff::08".to_string()), + // ServerNodeConfig::new("ff::09".to_string()), + // ]; + + let keepers = settings + .keepers + .iter() + .map(|host| KeeperNodeConfig::new(host.clone())) + .collect(); + + let remote_servers = settings + .remote_servers + .iter() + .map(|host| ServerNodeConfig::new(format!("{host:?}"))) + .collect(); let config = ClickhouseServerConfig::new( Utf8PathBuf::from_str("./").unwrap(), ServerId(settings.node_id), Utf8PathBuf::from_str("./").unwrap(), - Ipv6Addr::from_str("ff::08").unwrap(), + settings.listen_addr, keepers, - servers, + remote_servers, ); config.generate_xml_file().unwrap(); diff --git a/clickhouse-admin/types/src/config.rs b/clickhouse-admin/types/src/config.rs index 3337d733a9..b1119aa3a7 100644 --- a/clickhouse-admin/types/src/config.rs +++ b/clickhouse-admin/types/src/config.rs @@ -15,7 +15,8 @@ use schemars::{ JsonSchema, }; use serde::{Deserialize, Serialize}; -use std::{fmt::Display, net::Ipv6Addr}; +use std::fmt::Display; +use std::net::{Ipv4Addr, Ipv6Addr}; // Used for schemars to be able to be used with camino: // See https://github.com/camino-rs/camino/issues/91#issuecomment-2027908513 @@ -256,15 +257,16 @@ impl KeeperConfigsForReplica { // Otherwise, when running any query, a "Service not found" error // appears. // https://github.com/ClickHouse/ClickHouse/blob/a011990fd75628c63c7995c4f15475f1d4125d10/src/Coordination/KeeperStateManager.cpp#L149 - let parsed_host = match host.parse::() { - Ok(_) => format!("[{host}]"), - Err(_) => host.to_string(), + let sanitised_host = match host { + ClickhouseHost::Ipv6(h) => format!("[{h}]"), + ClickhouseHost::Ipv4(h) => h.to_string(), + ClickhouseHost::DomainName(h) => h.to_string(), }; s.push_str(&format!( " - {parsed_host} + {sanitised_host} {port} ", )); @@ -274,15 +276,23 @@ impl KeeperConfigsForReplica { } } +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum ClickhouseHost { + Ipv6(Ipv6Addr), + Ipv4(Ipv4Addr), + DomainName(String), +} + #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] pub struct KeeperNodeConfig { - pub host: String, + pub host: ClickhouseHost, pub port: u16, } impl KeeperNodeConfig { /// A new ClickHouse keeper node configuration with default port - pub fn new(host: String) -> Self { + pub fn new(host: ClickhouseHost) -> Self { let port = CLICKHOUSE_KEEPER_TCP_PORT; Self { host, port } } diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index c9cc076de5..d161b17490 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -153,14 +153,18 @@ impl ClickhouseKeeperConfig { #[cfg(test)] mod tests { - use std::{net::Ipv6Addr, str::FromStr}; + use std::{ + net::{Ipv4Addr, Ipv6Addr}, + str::FromStr, + }; use camino::Utf8PathBuf; use camino_tempfile::Builder; use crate::{ - ClickhouseKeeperConfig, ClickhouseServerConfig, KeeperId, - KeeperNodeConfig, RaftServerConfig, ServerId, ServerNodeConfig, + ClickhouseHost, ClickhouseKeeperConfig, ClickhouseServerConfig, + KeeperId, KeeperNodeConfig, RaftServerConfig, ServerId, + ServerNodeConfig, }; #[test] @@ -207,9 +211,15 @@ mod tests { ); let keepers = vec![ - KeeperNodeConfig::new("ff::01".to_string()), - KeeperNodeConfig::new("127.0.0.1".to_string()), - KeeperNodeConfig::new("we.dont.want.brackets.com".to_string()), + KeeperNodeConfig::new(ClickhouseHost::Ipv6( + Ipv6Addr::from_str("ff::01").unwrap(), + )), + KeeperNodeConfig::new(ClickhouseHost::Ipv4( + Ipv4Addr::from_str("127.0.0.1").unwrap(), + )), + KeeperNodeConfig::new(ClickhouseHost::DomainName( + "we.dont.want.brackets.com".to_string(), + )), ]; let servers = vec![ diff --git a/clickhouse-admin/types/testutils/replica-server-config.xml b/clickhouse-admin/types/testutils/replica-server-config.xml index 056fd2cc1c..6edf4beffe 100644 --- a/clickhouse-admin/types/testutils/replica-server-config.xml +++ b/clickhouse-admin/types/testutils/replica-server-config.xml @@ -90,7 +90,7 @@ - [ff::01] + [ff::1] 9181 diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index bcc98da6cb..27cf156a36 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -34,7 +34,7 @@ } } }, - "/server-node/generate-config": { + "/node/server/generate-config": { "post": { "summary": "Generate a ClickHouse configuration file for a server node on a specified", "description": "directory.", @@ -83,6 +83,48 @@ "clickhouse_address" ] }, + "ClickhouseHost": { + "oneOf": [ + { + "type": "object", + "properties": { + "ipv6": { + "type": "string", + "format": "ipv6" + } + }, + "required": [ + "ipv6" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "ipv4": { + "type": "string", + "format": "ipv4" + } + }, + "required": [ + "ipv4" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "domain_name": { + "type": "string" + } + }, + "required": [ + "domain_name" + ], + "additionalProperties": false + } + ] + }, "Error": { "description": "Error information from a response.", "type": "object", @@ -117,14 +159,41 @@ "ServerSettings": { "type": "object", "properties": { + "config_dir": { + "type": "string" + }, + "datastore_path": { + "type": "string" + }, + "keepers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ClickhouseHost" + } + }, + "listen_addr": { + "type": "string", + "format": "ipv6" + }, "node_id": { "type": "integer", "format": "uint64", "minimum": 0 + }, + "remote_servers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ClickhouseHost" + } } }, "required": [ - "node_id" + "config_dir", + "datastore_path", + "keepers", + "listen_addr", + "node_id", + "remote_servers" ] } }, From eb25fd417411901b7ddd8d38809e4151f1f2361c Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 30 Aug 2024 14:47:46 +1200 Subject: [PATCH 04/14] moar stronger types --- clickhouse-admin/src/clickward.rs | 18 +++---------- clickhouse-admin/types/src/config.rs | 25 ++++++++++++++----- clickhouse-admin/types/src/lib.rs | 23 +++++++++++++---- .../types/testutils/keeper-config.xml | 6 ++--- .../types/testutils/replica-server-config.xml | 4 +-- 5 files changed, 45 insertions(+), 31 deletions(-) diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index ad83eda208..81b567afcd 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -61,18 +61,6 @@ impl Clickward { &self, settings: ServerSettings, ) -> Result { - // TODO: This should be part of the request body - // let keepers = vec![ - // KeeperNodeConfig::new("ff::01".to_string()), - // KeeperNodeConfig::new("127.0.0.1".to_string()), - // KeeperNodeConfig::new("we.dont.want.brackets.com".to_string()), - // ]; - - // let servers = vec![ - // ServerNodeConfig::new("ff::08".to_string()), - // ServerNodeConfig::new("ff::09".to_string()), - // ]; - let keepers = settings .keepers .iter() @@ -82,13 +70,13 @@ impl Clickward { let remote_servers = settings .remote_servers .iter() - .map(|host| ServerNodeConfig::new(format!("{host:?}"))) + .map(|host| ServerNodeConfig::new(host.clone())) .collect(); let config = ClickhouseServerConfig::new( - Utf8PathBuf::from_str("./").unwrap(), + Utf8PathBuf::from_str(&settings.config_dir).unwrap(), ServerId(settings.node_id), - Utf8PathBuf::from_str("./").unwrap(), + Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), settings.listen_addr, keepers, remote_servers, diff --git a/clickhouse-admin/types/src/config.rs b/clickhouse-admin/types/src/config.rs index b1119aa3a7..f4221364dc 100644 --- a/clickhouse-admin/types/src/config.rs +++ b/clickhouse-admin/types/src/config.rs @@ -215,10 +215,16 @@ impl RemoteServers { for r in replicas { let ServerNodeConfig { host, port } = r; + let sanitised_host = match host { + ClickhouseHost::Ipv6(h) => h.to_string(), + ClickhouseHost::Ipv4(h) => h.to_string(), + ClickhouseHost::DomainName(h) => h.to_string(), + }; + s.push_str(&format!( " - {host} + {sanitised_host} {port} " )); @@ -300,13 +306,13 @@ impl KeeperNodeConfig { #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] pub struct ServerNodeConfig { - pub host: String, + pub host: ClickhouseHost, pub port: u16, } impl ServerNodeConfig { /// A new ClickHouse replica node configuration with default port - pub fn new(host: String) -> Self { + pub fn new(host: ClickhouseHost) -> Self { let port = CLICKHOUSE_TCP_PORT; Self { host, port } } @@ -389,11 +395,18 @@ impl RaftServers { let mut s = String::new(); for server in &self.servers { let RaftServerConfig { id, hostname, port } = server; + + let sanitised_host = match hostname { + ClickhouseHost::Ipv6(h) => h.to_string(), + ClickhouseHost::Ipv4(h) => h.to_string(), + ClickhouseHost::DomainName(h) => h.to_string(), + }; + s.push_str(&format!( " {id} - {hostname} + {sanitised_host} {port} " @@ -407,12 +420,12 @@ impl RaftServers { #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] pub struct RaftServerConfig { pub id: KeeperId, - pub hostname: String, + pub hostname: ClickhouseHost, pub port: u16, } impl RaftServerConfig { - pub fn new(id: KeeperId, hostname: String) -> Self { + pub fn new(id: KeeperId, hostname: ClickhouseHost) -> Self { Self { id, hostname, port: CLICKHOUSE_KEEPER_RAFT_PORT } } } diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index d161b17490..450c8305a5 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -176,9 +176,18 @@ mod tests { ); let keepers = vec![ - RaftServerConfig::new(KeeperId(1), "ff::01".to_string()), - RaftServerConfig::new(KeeperId(2), "ff::02".to_string()), - RaftServerConfig::new(KeeperId(3), "ff::03".to_string()), + RaftServerConfig::new( + KeeperId(1), + ClickhouseHost::Ipv6(Ipv6Addr::from_str("ff::01").unwrap()), + ), + RaftServerConfig::new( + KeeperId(2), + ClickhouseHost::Ipv4(Ipv4Addr::from_str("127.0.0.1").unwrap()), + ), + RaftServerConfig::new( + KeeperId(3), + ClickhouseHost::DomainName("ohai.com".to_string()), + ), ]; let config = ClickhouseKeeperConfig::new( @@ -223,8 +232,12 @@ mod tests { ]; let servers = vec![ - ServerNodeConfig::new("ff::08".to_string()), - ServerNodeConfig::new("ff::09".to_string()), + ServerNodeConfig::new(ClickhouseHost::Ipv6( + Ipv6Addr::from_str("ff::09").unwrap(), + )), + ServerNodeConfig::new(ClickhouseHost::DomainName( + "ohai.com".to_string(), + )), ]; let config = ClickhouseServerConfig::new( diff --git a/clickhouse-admin/types/testutils/keeper-config.xml b/clickhouse-admin/types/testutils/keeper-config.xml index e05cf9d954..b8533efb2c 100644 --- a/clickhouse-admin/types/testutils/keeper-config.xml +++ b/clickhouse-admin/types/testutils/keeper-config.xml @@ -25,19 +25,19 @@ 1 - ff::01 + ff::1 9234 2 - ff::02 + 127.0.0.1 9234 3 - ff::03 + ohai.com 9234 diff --git a/clickhouse-admin/types/testutils/replica-server-config.xml b/clickhouse-admin/types/testutils/replica-server-config.xml index 6edf4beffe..1c907e5749 100644 --- a/clickhouse-admin/types/testutils/replica-server-config.xml +++ b/clickhouse-admin/types/testutils/replica-server-config.xml @@ -77,11 +77,11 @@ true - ff::08 + ff::9 9000 - ff::09 + ohai.com 9000 From 2c31a80519d985281396cae70b4ecbdfed4da280 Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 30 Aug 2024 15:02:36 +1200 Subject: [PATCH 05/14] return information --- clickhouse-admin/api/src/lib.rs | 19 ++----------------- clickhouse-admin/src/clickward.rs | 17 +++++++++-------- clickhouse-admin/src/http_entrypoints.rs | 4 ++-- clickhouse-admin/types/src/lib.rs | 4 ++-- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index b86e5627a4..3324b7a5e8 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,7 +2,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use clickhouse_admin_types::config::ClickhouseHost; +use clickhouse_admin_types::config::{ClickhouseHost, ReplicaConfig}; use dropshot::{ HttpError, HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, }; @@ -32,7 +32,7 @@ pub trait ClickhouseAdminApi { async fn generate_server_config( rqctx: RequestContext, body: TypedBody, - ) -> Result, HttpError>; + ) -> Result, HttpError>; } #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] @@ -41,21 +41,6 @@ pub struct ClickhouseAddress { pub clickhouse_address: SocketAddrV6, } -// TODO: Perhaps change this response type for something better -// like an object with all the settings or something like that -/// Success response for server node configuration file generation -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct ServerConfigGenerateResponse { - pub success: bool, -} - -impl ServerConfigGenerateResponse { - pub fn success() -> Self { - Self { success: true } - } -} - #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct ServerSettings { diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index 81b567afcd..aea6a78528 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -3,14 +3,13 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use camino::Utf8PathBuf; -use clickhouse_admin_api::{ - ClickhouseAddress, ServerConfigGenerateResponse, ServerSettings, +use clickhouse_admin_api::{ClickhouseAddress, ServerSettings}; +use clickhouse_admin_types::config::{ + KeeperNodeConfig, ReplicaConfig, ServerNodeConfig, }; -use clickhouse_admin_types::config::{KeeperNodeConfig, ServerNodeConfig}; use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; -use std::io; use std::net::SocketAddrV6; use std::str::FromStr; @@ -19,7 +18,7 @@ pub enum ClickwardError { #[error("clickward failure")] Failure { #[source] - err: io::Error, + err: anyhow::Error, }, } @@ -60,7 +59,7 @@ impl Clickward { pub fn generate_server_config( &self, settings: ServerSettings, - ) -> Result { + ) -> Result { let keepers = settings .keepers .iter() @@ -82,8 +81,10 @@ impl Clickward { remote_servers, ); - config.generate_xml_file().unwrap(); + let replica_config = config + .generate_xml_file() + .map_err(|e| ClickwardError::Failure { err: e })?; - Ok(ServerConfigGenerateResponse::success()) + Ok(replica_config) } } diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 31f66aa355..e62f8e4486 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -4,6 +4,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; +use clickhouse_admin_types::config::ReplicaConfig; use dropshot::HttpError; use dropshot::{ HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, @@ -33,8 +34,7 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { async fn generate_server_config( rqctx: RequestContext, body: TypedBody, - ) -> Result, HttpError> - { + ) -> Result, HttpError> { let ctx = rqctx.context(); let server_settings = body.into_inner(); let output = ctx.clickward().generate_server_config(server_settings)?; diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index 450c8305a5..aa2b0f5a1a 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -78,7 +78,7 @@ impl ClickhouseServerConfig { } /// Generate a configuration file for a replica server node - pub fn generate_xml_file(&self) -> Result<()> { + pub fn generate_xml_file(&self) -> Result { let logger = LogConfig::new(self.datastore_path.clone(), NodeType::Server); let macros = Macros::new(self.id); @@ -98,7 +98,7 @@ impl ClickhouseServerConfig { f.write_all(config.to_xml().as_bytes())?; f.flush()?; rename(f.path(), self.config_dir.join("replica-server-config.xml"))?; - Ok(()) + Ok(config) } } From 04c1a946f5f4370cb6ccc421aeaf5f017fc75a1e Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 30 Aug 2024 15:18:32 +1200 Subject: [PATCH 06/14] remove test endpoint --- clickhouse-admin/api/src/lib.rs | 21 +------- clickhouse-admin/src/bin/clickhouse-admin.rs | 12 ++--- clickhouse-admin/src/clickward.rs | 19 ++----- clickhouse-admin/src/http_entrypoints.rs | 12 +---- sled-agent/src/services.rs | 54 ++++++-------------- smf/clickhouse-admin/manifest.xml | 3 +- 6 files changed, 26 insertions(+), 95 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index 3324b7a5e8..779e0e61c3 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -3,26 +3,15 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use clickhouse_admin_types::config::{ClickhouseHost, ReplicaConfig}; -use dropshot::{ - HttpError, HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, -}; +use dropshot::{HttpError, HttpResponseCreated, RequestContext, TypedBody}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::net::{Ipv6Addr, SocketAddrV6}; +use std::net::Ipv6Addr; #[dropshot::api_description] pub trait ClickhouseAdminApi { type Context; - /// Retrieve the address the ClickHouse server or keeper node is listening on. - #[endpoint { - method = GET, - path = "/node/address", - }] - async fn clickhouse_address( - rqctx: RequestContext, - ) -> Result, HttpError>; - /// Generate a ClickHouse configuration file for a server node on a specified /// directory. #[endpoint { @@ -35,12 +24,6 @@ pub trait ClickhouseAdminApi { ) -> Result, HttpError>; } -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct ClickhouseAddress { - pub clickhouse_address: SocketAddrV6, -} - #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct ServerSettings { diff --git a/clickhouse-admin/src/bin/clickhouse-admin.rs b/clickhouse-admin/src/bin/clickhouse-admin.rs index 6f28a82804..734cd91e8d 100644 --- a/clickhouse-admin/src/bin/clickhouse-admin.rs +++ b/clickhouse-admin/src/bin/clickhouse-admin.rs @@ -20,14 +20,8 @@ use std::net::{SocketAddr, SocketAddrV6}; enum Args { /// Start the ClickHouse admin server Run { - // TODO: This address is solely for testing now. We should remove it - // once we have more endpoints up and running. - /// Socket address for a running clickhouse server or keeper instance - #[clap(long, short = 'a', action)] - clickhouse_address: SocketAddrV6, - /// Address on which this server should run - #[clap(long, short = 'H', action)] + #[clap(long, short = 'a', action)] http_address: SocketAddrV6, /// Path to the server configuration file @@ -47,12 +41,12 @@ async fn main_impl() -> Result<(), CmdError> { let args = Args::parse(); match args { - Args::Run { clickhouse_address, http_address, config } => { + Args::Run { http_address, config } => { let mut config = Config::from_file(&config) .map_err(|err| CmdError::Failure(anyhow!(err)))?; config.dropshot.bind_address = SocketAddr::V6(http_address); - let clickward = Clickward::new(clickhouse_address); + let clickward = Clickward::new(); let server = omicron_clickhouse_admin::start_server(clickward, config) diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index aea6a78528..e92b1ab7a0 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -3,14 +3,13 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use camino::Utf8PathBuf; -use clickhouse_admin_api::{ClickhouseAddress, ServerSettings}; +use clickhouse_admin_api::ServerSettings; use clickhouse_admin_types::config::{ KeeperNodeConfig, ReplicaConfig, ServerNodeConfig, }; use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; -use std::net::SocketAddrV6; use std::str::FromStr; #[derive(Debug, thiserror::Error, SlogInlineError)] @@ -39,21 +38,11 @@ impl From for HttpError { } #[derive(Debug)] -pub struct Clickward { - // TODO: Remove address? - clickhouse_address: SocketAddrV6, -} +pub struct Clickward {} impl Clickward { - pub fn new(clickhouse_address: SocketAddrV6) -> Self { - Self { clickhouse_address } - } - - // TODO: Remove this endpoint? - pub fn clickhouse_address( - &self, - ) -> Result { - Ok(ClickhouseAddress { clickhouse_address: self.clickhouse_address }) + pub fn new() -> Self { + Self {} } pub fn generate_server_config( diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index e62f8e4486..fbab6ce95c 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -6,9 +6,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use clickhouse_admin_types::config::ReplicaConfig; use dropshot::HttpError; -use dropshot::{ - HttpResponseCreated, HttpResponseOk, RequestContext, TypedBody, -}; +use dropshot::{HttpResponseCreated, RequestContext, TypedBody}; use std::sync::Arc; type ClickhouseApiDescription = dropshot::ApiDescription>; @@ -23,14 +21,6 @@ enum ClickhouseAdminImpl {} impl ClickhouseAdminApi for ClickhouseAdminImpl { type Context = Arc; - async fn clickhouse_address( - rqctx: RequestContext, - ) -> Result, HttpError> { - let ctx = rqctx.context(); - let output = ctx.clickward().clickhouse_address()?; - Ok(HttpResponseOk(output)) - } - async fn generate_server_config( rqctx: RequestContext, body: TypedBody, diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 7677dfbd8a..f386fd1d0f 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -1573,12 +1573,6 @@ impl ServiceManager { .add_property_group(config), ); - let ch_address = SocketAddr::new( - IpAddr::V6(listen_addr), - CLICKHOUSE_HTTP_PORT, - ) - .to_string(); - let admin_address = SocketAddr::new( IpAddr::V6(listen_addr), CLICKHOUSE_ADMIN_PORT, @@ -1586,13 +1580,11 @@ impl ServiceManager { .to_string(); let clickhouse_admin_config = - PropertyGroupBuilder::new("config") - .add_property( - "clickhouse_address", - "astring", - ch_address, - ) - .add_property("http_address", "astring", admin_address); + PropertyGroupBuilder::new("config").add_property( + "http_address", + "astring", + admin_address, + ); let clickhouse_admin_service = ServiceBuilder::new("oxide/clickhouse-admin").add_instance( ServiceInstanceBuilder::new("default") @@ -1654,12 +1646,6 @@ impl ServiceManager { .add_property_group(config), ); - let ch_address = SocketAddr::new( - IpAddr::V6(listen_addr), - CLICKHOUSE_HTTP_PORT, - ) - .to_string(); - let admin_address = SocketAddr::new( IpAddr::V6(listen_addr), CLICKHOUSE_ADMIN_PORT, @@ -1667,13 +1653,11 @@ impl ServiceManager { .to_string(); let clickhouse_admin_config = - PropertyGroupBuilder::new("config") - .add_property( - "clickhouse_address", - "astring", - ch_address, - ) - .add_property("http_address", "astring", admin_address); + PropertyGroupBuilder::new("config").add_property( + "http_address", + "astring", + admin_address, + ); let clickhouse_admin_service = ServiceBuilder::new("oxide/clickhouse-admin").add_instance( ServiceInstanceBuilder::new("default") @@ -1738,12 +1722,6 @@ impl ServiceManager { .add_property_group(config), ); - let ch_address = SocketAddr::new( - IpAddr::V6(listen_addr), - CLICKHOUSE_HTTP_PORT, - ) - .to_string(); - let admin_address = SocketAddr::new( IpAddr::V6(listen_addr), CLICKHOUSE_ADMIN_PORT, @@ -1751,13 +1729,11 @@ impl ServiceManager { .to_string(); let clickhouse_admin_config = - PropertyGroupBuilder::new("config") - .add_property( - "clickhouse_address", - "astring", - ch_address, - ) - .add_property("http_address", "astring", admin_address); + PropertyGroupBuilder::new("config").add_property( + "http_address", + "astring", + admin_address, + ); let clickhouse_admin_service = ServiceBuilder::new("oxide/clickhouse-admin").add_instance( ServiceInstanceBuilder::new("default") diff --git a/smf/clickhouse-admin/manifest.xml b/smf/clickhouse-admin/manifest.xml index 435f8a86ac..84d61e4caa 100644 --- a/smf/clickhouse-admin/manifest.xml +++ b/smf/clickhouse-admin/manifest.xml @@ -17,12 +17,11 @@ - From c128ef9c7a5d5d6af898adcd796dcb047cbf4d9c Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 30 Aug 2024 16:11:13 +1200 Subject: [PATCH 07/14] Simplify types --- clickhouse-admin/api/src/lib.rs | 15 ++++++++++- clickhouse-admin/src/clickward.rs | 21 +++------------ clickhouse-admin/types/src/lib.rs | 45 +++++++++++++------------------ 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index 779e0e61c3..0b641de0e0 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,7 +2,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use clickhouse_admin_types::config::{ClickhouseHost, ReplicaConfig}; +use clickhouse_admin_types::config::{ + ClickhouseHost, KeeperConfig, ReplicaConfig, +}; use dropshot::{HttpError, HttpResponseCreated, RequestContext, TypedBody}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -22,6 +24,17 @@ pub trait ClickhouseAdminApi { rqctx: RequestContext, body: TypedBody, ) -> Result, HttpError>; + + // /// Generate a ClickHouse configuration file for a keeper node on a specified + // /// directory. + // #[endpoint { + // method = POST, + // path = "/node/keeper/generate-config", + // }] + // async fn generate_keeper_config( + // rqctx: RequestContext, + // body: TypedBody, + // ) -> Result, HttpError>; } #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index e92b1ab7a0..8aa61d72da 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -4,9 +4,7 @@ use camino::Utf8PathBuf; use clickhouse_admin_api::ServerSettings; -use clickhouse_admin_types::config::{ - KeeperNodeConfig, ReplicaConfig, ServerNodeConfig, -}; +use clickhouse_admin_types::config::ReplicaConfig; use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; @@ -49,25 +47,14 @@ impl Clickward { &self, settings: ServerSettings, ) -> Result { - let keepers = settings - .keepers - .iter() - .map(|host| KeeperNodeConfig::new(host.clone())) - .collect(); - - let remote_servers = settings - .remote_servers - .iter() - .map(|host| ServerNodeConfig::new(host.clone())) - .collect(); - let config = ClickhouseServerConfig::new( + // We can safely call unwrap here as this method is infallible Utf8PathBuf::from_str(&settings.config_dir).unwrap(), ServerId(settings.node_id), Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), settings.listen_addr, - keepers, - remote_servers, + settings.keepers, + settings.remote_servers, ); let replica_config = config diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index aa2b0f5a1a..2608baebd8 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -71,9 +71,19 @@ impl ClickhouseServerConfig { id: ServerId, datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, - keepers: Vec, - servers: Vec, + keepers: Vec, + servers: Vec, ) -> Self { + let keepers = keepers + .iter() + .map(|host| KeeperNodeConfig::new(host.clone())) + .collect(); + + let servers = servers + .iter() + .map(|host| ServerNodeConfig::new(host.clone())) + .collect(); + Self { config_dir, id, datastore_path, listen_addr, keepers, servers } } @@ -119,13 +129,7 @@ impl ClickhouseKeeperConfig { datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, ) -> Self { - ClickhouseKeeperConfig { - config_dir, - id, - raft_servers, - datastore_path, - listen_addr, - } + Self { config_dir, id, raft_servers, datastore_path, listen_addr } } /// Generate a configuration file for a keeper node @@ -163,8 +167,7 @@ mod tests { use crate::{ ClickhouseHost, ClickhouseKeeperConfig, ClickhouseServerConfig, - KeeperId, KeeperNodeConfig, RaftServerConfig, ServerId, - ServerNodeConfig, + KeeperId, RaftServerConfig, ServerId, }; #[test] @@ -220,24 +223,14 @@ mod tests { ); let keepers = vec![ - KeeperNodeConfig::new(ClickhouseHost::Ipv6( - Ipv6Addr::from_str("ff::01").unwrap(), - )), - KeeperNodeConfig::new(ClickhouseHost::Ipv4( - Ipv4Addr::from_str("127.0.0.1").unwrap(), - )), - KeeperNodeConfig::new(ClickhouseHost::DomainName( - "we.dont.want.brackets.com".to_string(), - )), + ClickhouseHost::Ipv6(Ipv6Addr::from_str("ff::01").unwrap()), + ClickhouseHost::Ipv4(Ipv4Addr::from_str("127.0.0.1").unwrap()), + ClickhouseHost::DomainName("we.dont.want.brackets.com".to_string()), ]; let servers = vec![ - ServerNodeConfig::new(ClickhouseHost::Ipv6( - Ipv6Addr::from_str("ff::09").unwrap(), - )), - ServerNodeConfig::new(ClickhouseHost::DomainName( - "ohai.com".to_string(), - )), + ClickhouseHost::Ipv6(Ipv6Addr::from_str("ff::09").unwrap()), + ClickhouseHost::DomainName("ohai.com".to_string()), ]; let config = ClickhouseServerConfig::new( From 27ba91f2d40708d2f4279942a8b90a6a2339ecd3 Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 30 Aug 2024 17:16:30 +1200 Subject: [PATCH 08/14] generate keeper config --- clickhouse-admin/api/src/lib.rs | 32 +- clickhouse-admin/src/clickward.rs | 27 +- clickhouse-admin/src/http_entrypoints.rs | 12 +- clickhouse-admin/types/src/config.rs | 16 +- clickhouse-admin/types/src/lib.rs | 41 ++- openapi/clickhouse-admin.json | 382 +++++++++++++++++++++-- 6 files changed, 453 insertions(+), 57 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index 0b641de0e0..b2ff2d8c5a 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use clickhouse_admin_types::config::{ - ClickhouseHost, KeeperConfig, ReplicaConfig, + ClickhouseHost, KeeperConfig, RaftServerSettings, ReplicaConfig, }; use dropshot::{HttpError, HttpResponseCreated, RequestContext, TypedBody}; use schemars::JsonSchema; @@ -25,16 +25,16 @@ pub trait ClickhouseAdminApi { body: TypedBody, ) -> Result, HttpError>; - // /// Generate a ClickHouse configuration file for a keeper node on a specified - // /// directory. - // #[endpoint { - // method = POST, - // path = "/node/keeper/generate-config", - // }] - // async fn generate_keeper_config( - // rqctx: RequestContext, - // body: TypedBody, - // ) -> Result, HttpError>; + /// Generate a ClickHouse configuration file for a keeper node on a specified + /// directory. + #[endpoint { + method = POST, + path = "/node/keeper/generate-config", + }] + async fn generate_keeper_config( + rqctx: RequestContext, + body: TypedBody, + ) -> Result, HttpError>; } #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] @@ -47,3 +47,13 @@ pub struct ServerSettings { pub datastore_path: String, pub listen_addr: Ipv6Addr, } + +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct KeeperSettings { + pub node_id: u64, + pub keepers: Vec, + pub config_dir: String, + pub datastore_path: String, + pub listen_addr: Ipv6Addr, +} diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index 8aa61d72da..65b36eef17 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -3,9 +3,11 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use camino::Utf8PathBuf; -use clickhouse_admin_api::ServerSettings; -use clickhouse_admin_types::config::ReplicaConfig; -use clickhouse_admin_types::{ClickhouseServerConfig, ServerId}; +use clickhouse_admin_api::{KeeperSettings, ServerSettings}; +use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; +use clickhouse_admin_types::{ + ClickhouseKeeperConfig, ClickhouseServerConfig, KeeperId, ServerId, +}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; use std::str::FromStr; @@ -63,4 +65,23 @@ impl Clickward { Ok(replica_config) } + + pub fn generate_keeper_config( + &self, + settings: KeeperSettings, + ) -> Result { + let config = ClickhouseKeeperConfig::new( + Utf8PathBuf::from_str(&settings.config_dir).unwrap(), + KeeperId(settings.node_id), + settings.keepers, + Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), + settings.listen_addr, + ); + + let keeper_config = config + .generate_xml_file() + .map_err(|e| ClickwardError::Failure { err: e })?; + + Ok(keeper_config) + } } diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index fbab6ce95c..3a6810941e 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -4,7 +4,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; -use clickhouse_admin_types::config::ReplicaConfig; +use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; use dropshot::HttpError; use dropshot::{HttpResponseCreated, RequestContext, TypedBody}; use std::sync::Arc; @@ -30,4 +30,14 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { let output = ctx.clickward().generate_server_config(server_settings)?; Ok(HttpResponseCreated(output)) } + + async fn generate_keeper_config( + rqctx: RequestContext, + body: TypedBody, + ) -> Result, HttpError> { + let ctx = rqctx.context(); + let keeper_settings = body.into_inner(); + let output = ctx.clickward().generate_keeper_config(keeper_settings)?; + Ok(HttpResponseCreated(output)) + } } diff --git a/clickhouse-admin/types/src/config.rs b/clickhouse-admin/types/src/config.rs index f4221364dc..86eb6c65ce 100644 --- a/clickhouse-admin/types/src/config.rs +++ b/clickhouse-admin/types/src/config.rs @@ -417,6 +417,13 @@ impl RaftServers { } } +#[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub struct RaftServerSettings { + pub id: KeeperId, + pub host: ClickhouseHost, +} + #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] pub struct RaftServerConfig { pub id: KeeperId, @@ -425,8 +432,12 @@ pub struct RaftServerConfig { } impl RaftServerConfig { - pub fn new(id: KeeperId, hostname: ClickhouseHost) -> Self { - Self { id, hostname, port: CLICKHOUSE_KEEPER_RAFT_PORT } + pub fn new(settings: RaftServerSettings) -> Self { + Self { + id: settings.id, + hostname: settings.host, + port: CLICKHOUSE_KEEPER_RAFT_PORT, + } } } @@ -516,6 +527,7 @@ impl KeeperConfig { } #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] pub enum LogLevel { Trace, Debug, diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index 2608baebd8..99d29aa54d 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -125,15 +125,20 @@ impl ClickhouseKeeperConfig { pub fn new( config_dir: Utf8PathBuf, id: KeeperId, - raft_servers: Vec, + raft_servers: Vec, datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, ) -> Self { + let raft_servers = raft_servers + .iter() + .map(|settings| RaftServerConfig::new(settings.clone())) + .collect(); + Self { config_dir, id, raft_servers, datastore_path, listen_addr } } /// Generate a configuration file for a keeper node - pub fn generate_xml_file(&self) -> Result<()> { + pub fn generate_xml_file(&self) -> Result { let logger = LogConfig::new(self.datastore_path.clone(), NodeType::Keeper); let raft_config = RaftServers::new(self.raft_servers.clone()); @@ -151,7 +156,7 @@ impl ClickhouseKeeperConfig { f.write_all(config.to_xml().as_bytes())?; f.flush()?; rename(f.path(), self.config_dir.join("keeper-config.xml"))?; - Ok(()) + Ok(config) } } @@ -167,7 +172,7 @@ mod tests { use crate::{ ClickhouseHost, ClickhouseKeeperConfig, ClickhouseServerConfig, - KeeperId, RaftServerConfig, ServerId, + KeeperId, RaftServerSettings, ServerId, }; #[test] @@ -179,18 +184,22 @@ mod tests { ); let keepers = vec![ - RaftServerConfig::new( - KeeperId(1), - ClickhouseHost::Ipv6(Ipv6Addr::from_str("ff::01").unwrap()), - ), - RaftServerConfig::new( - KeeperId(2), - ClickhouseHost::Ipv4(Ipv4Addr::from_str("127.0.0.1").unwrap()), - ), - RaftServerConfig::new( - KeeperId(3), - ClickhouseHost::DomainName("ohai.com".to_string()), - ), + RaftServerSettings { + id: KeeperId(1), + host: ClickhouseHost::Ipv6( + Ipv6Addr::from_str("ff::01").unwrap(), + ), + }, + RaftServerSettings { + id: KeeperId(2), + host: ClickhouseHost::Ipv4( + Ipv4Addr::from_str("127.0.0.1").unwrap(), + ), + }, + RaftServerSettings { + id: KeeperId(3), + host: ClickhouseHost::DomainName("ohai.com".to_string()), + }, ]; let config = ClickhouseKeeperConfig::new( diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index 27cf156a36..ddb1d52152 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -10,17 +10,28 @@ "version": "0.0.1" }, "paths": { - "/node/address": { - "get": { - "summary": "Retrieve the address the ClickHouse server or keeper node is listening on.", - "operationId": "clickhouse_address", + "/node/keeper/generate-config": { + "post": { + "summary": "Generate a ClickHouse configuration file for a keeper node on a specified", + "description": "directory.", + "operationId": "generate_keeper_config", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KeeperSettings" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "successful operation", + "201": { + "description": "successful creation", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ClickhouseAddress" + "$ref": "#/components/schemas/KeeperConfig" } } } @@ -55,7 +66,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServerConfigGenerateResponse" + "$ref": "#/components/schemas/ReplicaConfig" } } } @@ -72,17 +83,6 @@ }, "components": { "schemas": { - "ClickhouseAddress": { - "type": "object", - "properties": { - "clickhouse_address": { - "type": "string" - } - }, - "required": [ - "clickhouse_address" - ] - }, "ClickhouseHost": { "oneOf": [ { @@ -144,16 +144,350 @@ "request_id" ] }, - "ServerConfigGenerateResponse": { - "description": "Success response for server node configuration file generation", + "KeeperConfig": { + "description": "Configuration for a ClickHouse keeper", + "type": "object", + "properties": { + "coordination_settings": { + "$ref": "#/components/schemas/KeeperCoordinationSettings" + }, + "listen_host": { + "type": "string", + "format": "ipv6" + }, + "log_storage_path": { + "type": "string", + "format": "Utf8PathBuf" + }, + "logger": { + "$ref": "#/components/schemas/LogConfig" + }, + "raft_config": { + "$ref": "#/components/schemas/RaftServers" + }, + "server_id": { + "$ref": "#/components/schemas/KeeperId" + }, + "snapshot_storage_path": { + "type": "string", + "format": "Utf8PathBuf" + }, + "tcp_port": { + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "coordination_settings", + "listen_host", + "log_storage_path", + "logger", + "raft_config", + "server_id", + "snapshot_storage_path", + "tcp_port" + ] + }, + "KeeperConfigsForReplica": { + "type": "object", + "properties": { + "nodes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KeeperNodeConfig" + } + } + }, + "required": [ + "nodes" + ] + }, + "KeeperCoordinationSettings": { + "type": "object", + "properties": { + "operation_timeout_ms": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "raft_logs_level": { + "$ref": "#/components/schemas/LogLevel" + }, + "session_timeout_ms": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "operation_timeout_ms", + "raft_logs_level", + "session_timeout_ms" + ] + }, + "KeeperId": { + "description": "A unique ID for a ClickHouse Keeper", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "KeeperNodeConfig": { "type": "object", "properties": { - "success": { - "type": "boolean" + "host": { + "$ref": "#/components/schemas/ClickhouseHost" + }, + "port": { + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "host", + "port" + ] + }, + "KeeperSettings": { + "type": "object", + "properties": { + "config_dir": { + "type": "string" + }, + "datastore_path": { + "type": "string" + }, + "keepers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RaftServerSettings" + } + }, + "listen_addr": { + "type": "string", + "format": "ipv6" + }, + "node_id": { + "type": "integer", + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "config_dir", + "datastore_path", + "keepers", + "listen_addr", + "node_id" + ] + }, + "LogConfig": { + "type": "object", + "properties": { + "count": { + "type": "integer", + "format": "uint", + "minimum": 0 + }, + "errorlog": { + "type": "string", + "format": "Utf8PathBuf" + }, + "level": { + "$ref": "#/components/schemas/LogLevel" + }, + "log": { + "type": "string", + "format": "Utf8PathBuf" + }, + "size": { + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "count", + "errorlog", + "level", + "log", + "size" + ] + }, + "LogLevel": { + "type": "string", + "enum": [ + "trace", + "debug" + ] + }, + "Macros": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "replica": { + "$ref": "#/components/schemas/ServerId" + }, + "shard": { + "type": "integer", + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "cluster", + "replica", + "shard" + ] + }, + "RaftServerConfig": { + "type": "object", + "properties": { + "hostname": { + "$ref": "#/components/schemas/ClickhouseHost" + }, + "id": { + "$ref": "#/components/schemas/KeeperId" + }, + "port": { + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "hostname", + "id", + "port" + ] + }, + "RaftServerSettings": { + "type": "object", + "properties": { + "host": { + "$ref": "#/components/schemas/ClickhouseHost" + }, + "id": { + "$ref": "#/components/schemas/KeeperId" + } + }, + "required": [ + "host", + "id" + ] + }, + "RaftServers": { + "type": "object", + "properties": { + "servers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RaftServerConfig" + } + } + }, + "required": [ + "servers" + ] + }, + "RemoteServers": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "replicas": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServerNodeConfig" + } + }, + "secret": { + "type": "string" + } + }, + "required": [ + "cluster", + "replicas", + "secret" + ] + }, + "ReplicaConfig": { + "description": "Configuration for a ClickHouse replica server", + "type": "object", + "properties": { + "data_path": { + "type": "string", + "format": "Utf8PathBuf" + }, + "http_port": { + "type": "integer", + "format": "uint16", + "minimum": 0 + }, + "interserver_http_port": { + "type": "integer", + "format": "uint16", + "minimum": 0 + }, + "keepers": { + "$ref": "#/components/schemas/KeeperConfigsForReplica" + }, + "listen_host": { + "type": "string", + "format": "ipv6" + }, + "logger": { + "$ref": "#/components/schemas/LogConfig" + }, + "macros": { + "$ref": "#/components/schemas/Macros" + }, + "remote_servers": { + "$ref": "#/components/schemas/RemoteServers" + }, + "tcp_port": { + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "data_path", + "http_port", + "interserver_http_port", + "keepers", + "listen_host", + "logger", + "macros", + "remote_servers", + "tcp_port" + ] + }, + "ServerId": { + "description": "A unique ID for a Clickhouse Server", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "ServerNodeConfig": { + "type": "object", + "properties": { + "host": { + "$ref": "#/components/schemas/ClickhouseHost" + }, + "port": { + "type": "integer", + "format": "uint16", + "minimum": 0 } }, "required": [ - "success" + "host", + "port" ] }, "ServerSettings": { From 0412185c298c5a85b8a12519187f6fb4a87332bb Mon Sep 17 00:00:00 2001 From: karencfv Date: Mon, 2 Sep 2024 17:42:27 +1200 Subject: [PATCH 09/14] take generation number --- clickhouse-admin/api/src/lib.rs | 26 ++++++++++----- clickhouse-admin/src/clickward.rs | 8 ++--- clickhouse-admin/src/http_entrypoints.rs | 9 ++++-- clickhouse-admin/types/src/config.rs | 2 +- clickhouse-admin/types/src/lib.rs | 5 ++- openapi/clickhouse-admin.json | 40 +++++++++++++++++++----- 6 files changed, 65 insertions(+), 25 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index b2ff2d8c5a..bf1458b9f6 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -5,11 +5,19 @@ use clickhouse_admin_types::config::{ ClickhouseHost, KeeperConfig, RaftServerSettings, ReplicaConfig, }; -use dropshot::{HttpError, HttpResponseCreated, RequestContext, TypedBody}; +use clickhouse_admin_types::{KeeperId, ServerId}; +use dropshot::{HttpError, HttpResponseCreated, Path, RequestContext, TypedBody}; +use omicron_common::api::external::Generation; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::net::Ipv6Addr; +#[derive(Debug, Deserialize, JsonSchema)] +pub struct GenerationNum { + /// A unique identifier for the configuration generation. + pub generation: Generation, +} + #[dropshot::api_description] pub trait ClickhouseAdminApi { type Context; @@ -18,10 +26,11 @@ pub trait ClickhouseAdminApi { /// directory. #[endpoint { method = POST, - path = "/node/server/generate-config", + path = "/node/server/generate-config/{generation}", }] async fn generate_server_config( rqctx: RequestContext, + path: Path, body: TypedBody, ) -> Result, HttpError>; @@ -29,10 +38,11 @@ pub trait ClickhouseAdminApi { /// directory. #[endpoint { method = POST, - path = "/node/keeper/generate-config", + path = "/node/keeper/generate-config/{generation}", }] async fn generate_keeper_config( rqctx: RequestContext, + path: Path, body: TypedBody, ) -> Result, HttpError>; } @@ -40,20 +50,20 @@ pub trait ClickhouseAdminApi { #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct ServerSettings { - pub node_id: u64, - pub keepers: Vec, - pub remote_servers: Vec, pub config_dir: String, pub datastore_path: String, pub listen_addr: Ipv6Addr, + pub node_id: ServerId, + pub keepers: Vec, + pub remote_servers: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct KeeperSettings { - pub node_id: u64, - pub keepers: Vec, pub config_dir: String, pub datastore_path: String, pub listen_addr: Ipv6Addr, + pub node_id: KeeperId, + pub keepers: Vec, } diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index 65b36eef17..8e412ee99c 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -5,9 +5,7 @@ use camino::Utf8PathBuf; use clickhouse_admin_api::{KeeperSettings, ServerSettings}; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use clickhouse_admin_types::{ - ClickhouseKeeperConfig, ClickhouseServerConfig, KeeperId, ServerId, -}; +use clickhouse_admin_types::{ClickhouseKeeperConfig, ClickhouseServerConfig}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; use std::str::FromStr; @@ -52,7 +50,7 @@ impl Clickward { let config = ClickhouseServerConfig::new( // We can safely call unwrap here as this method is infallible Utf8PathBuf::from_str(&settings.config_dir).unwrap(), - ServerId(settings.node_id), + settings.node_id, Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), settings.listen_addr, settings.keepers, @@ -72,7 +70,7 @@ impl Clickward { ) -> Result { let config = ClickhouseKeeperConfig::new( Utf8PathBuf::from_str(&settings.config_dir).unwrap(), - KeeperId(settings.node_id), + settings.node_id, settings.keepers, Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), settings.listen_addr, diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 3a6810941e..58221490fb 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,8 +5,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use dropshot::HttpError; -use dropshot::{HttpResponseCreated, RequestContext, TypedBody}; +use dropshot::{HttpError, HttpResponseCreated, Path, RequestContext, TypedBody}; use std::sync::Arc; type ClickhouseApiDescription = dropshot::ApiDescription>; @@ -23,21 +22,27 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { async fn generate_server_config( rqctx: RequestContext, + path: Path, body: TypedBody, ) -> Result, HttpError> { let ctx = rqctx.context(); let server_settings = body.into_inner(); let output = ctx.clickward().generate_server_config(server_settings)?; + // TODO: Do something with the generation number + println!("{path:?}"); Ok(HttpResponseCreated(output)) } async fn generate_keeper_config( rqctx: RequestContext, + path: Path, body: TypedBody, ) -> Result, HttpError> { let ctx = rqctx.context(); let keeper_settings = body.into_inner(); let output = ctx.clickward().generate_keeper_config(keeper_settings)?; + // TODO: Do something with the generation number + println!("{path:?}"); Ok(HttpResponseCreated(output)) } } diff --git a/clickhouse-admin/types/src/config.rs b/clickhouse-admin/types/src/config.rs index 86eb6c65ce..a31295834a 100644 --- a/clickhouse-admin/types/src/config.rs +++ b/clickhouse-admin/types/src/config.rs @@ -20,7 +20,7 @@ use std::net::{Ipv4Addr, Ipv6Addr}; // Used for schemars to be able to be used with camino: // See https://github.com/camino-rs/camino/issues/91#issuecomment-2027908513 -fn path_schema(gen: &mut SchemaGenerator) -> Schema { +pub fn path_schema(gen: &mut SchemaGenerator) -> Schema { let mut schema: SchemaObject = ::json_schema(gen).into(); schema.format = Some("Utf8PathBuf".to_owned()); schema.into() diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index 99d29aa54d..0e0ff968da 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -112,11 +112,14 @@ impl ClickhouseServerConfig { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] pub struct ClickhouseKeeperConfig { + #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, pub id: KeeperId, pub raft_servers: Vec, + #[schemars(schema_with = "path_schema")] pub datastore_path: Utf8PathBuf, pub listen_addr: Ipv6Addr, } diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index ddb1d52152..cda308cedc 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -10,11 +10,22 @@ "version": "0.0.1" }, "paths": { - "/node/keeper/generate-config": { + "/node/keeper/generate-config/{generation}": { "post": { "summary": "Generate a ClickHouse configuration file for a keeper node on a specified", "description": "directory.", "operationId": "generate_keeper_config", + "parameters": [ + { + "in": "path", + "name": "generation", + "description": "A unique identifier for the configuration generation.", + "required": true, + "schema": { + "$ref": "#/components/schemas/Generation" + } + } + ], "requestBody": { "content": { "application/json": { @@ -45,11 +56,22 @@ } } }, - "/node/server/generate-config": { + "/node/server/generate-config/{generation}": { "post": { "summary": "Generate a ClickHouse configuration file for a server node on a specified", "description": "directory.", "operationId": "generate_server_config", + "parameters": [ + { + "in": "path", + "name": "generation", + "description": "A unique identifier for the configuration generation.", + "required": true, + "schema": { + "$ref": "#/components/schemas/Generation" + } + } + ], "requestBody": { "content": { "application/json": { @@ -269,9 +291,7 @@ "format": "ipv6" }, "node_id": { - "type": "integer", - "format": "uint64", - "minimum": 0 + "$ref": "#/components/schemas/KeeperId" } }, "required": [ @@ -510,9 +530,7 @@ "format": "ipv6" }, "node_id": { - "type": "integer", - "format": "uint64", - "minimum": 0 + "$ref": "#/components/schemas/ServerId" }, "remote_servers": { "type": "array", @@ -529,6 +547,12 @@ "node_id", "remote_servers" ] + }, + "Generation": { + "description": "Generation numbers stored in the database, used for optimistic concurrency control", + "type": "integer", + "format": "uint64", + "minimum": 0 } }, "responses": { From 112bdc377018be4774fb69787a92a6b85b468503 Mon Sep 17 00:00:00 2001 From: karencfv Date: Mon, 2 Sep 2024 18:17:21 +1200 Subject: [PATCH 10/14] Simplify server types --- Cargo.lock | 1 + clickhouse-admin/api/Cargo.toml | 1 + clickhouse-admin/api/src/lib.rs | 26 ++++------- clickhouse-admin/src/clickward.rs | 24 +++------- clickhouse-admin/src/http_entrypoints.rs | 5 +- clickhouse-admin/types/src/lib.rs | 58 ++++++++++++++---------- openapi/clickhouse-admin.json | 12 +++-- 7 files changed, 65 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8666963ed8..c25eda9d99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,6 +1119,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "clickhouse-admin-api" version = "0.1.0" dependencies = [ + "camino", "clickhouse-admin-types", "dropshot 0.10.2-dev", "omicron-common", diff --git a/clickhouse-admin/api/Cargo.toml b/clickhouse-admin/api/Cargo.toml index a5d1dca202..e3bb96d001 100644 --- a/clickhouse-admin/api/Cargo.toml +++ b/clickhouse-admin/api/Cargo.toml @@ -8,6 +8,7 @@ license = "MPL-2.0" workspace = true [dependencies] +camino.workspace = true clickhouse-admin-types.workspace = true dropshot.workspace = true omicron-common.workspace = true diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index bf1458b9f6..a5f1ff8924 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,11 +2,14 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. +use camino::Utf8PathBuf; use clickhouse_admin_types::config::{ - ClickhouseHost, KeeperConfig, RaftServerSettings, ReplicaConfig, + path_schema, KeeperConfig, RaftServerSettings, ReplicaConfig, +}; +use clickhouse_admin_types::{ServerSettings, KeeperId}; +use dropshot::{ + HttpError, HttpResponseCreated, Path, RequestContext, TypedBody, }; -use clickhouse_admin_types::{KeeperId, ServerId}; -use dropshot::{HttpError, HttpResponseCreated, Path, RequestContext, TypedBody}; use omicron_common::api::external::Generation; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -47,22 +50,13 @@ pub trait ClickhouseAdminApi { ) -> Result, HttpError>; } -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct ServerSettings { - pub config_dir: String, - pub datastore_path: String, - pub listen_addr: Ipv6Addr, - pub node_id: ServerId, - pub keepers: Vec, - pub remote_servers: Vec, -} - #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct KeeperSettings { - pub config_dir: String, - pub datastore_path: String, + #[schemars(schema_with = "path_schema")] + pub config_dir: Utf8PathBuf, + #[schemars(schema_with = "path_schema")] + pub datastore_path: Utf8PathBuf, pub listen_addr: Ipv6Addr, pub node_id: KeeperId, pub keepers: Vec, diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index 8e412ee99c..e2ba5f3524 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -2,13 +2,11 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use camino::Utf8PathBuf; -use clickhouse_admin_api::{KeeperSettings, ServerSettings}; +use clickhouse_admin_api::KeeperSettings; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use clickhouse_admin_types::{ClickhouseKeeperConfig, ClickhouseServerConfig}; +use clickhouse_admin_types::{ClickhouseKeeperConfig, ServerSettings}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; -use std::str::FromStr; #[derive(Debug, thiserror::Error, SlogInlineError)] pub enum ClickwardError { @@ -46,18 +44,8 @@ impl Clickward { pub fn generate_server_config( &self, settings: ServerSettings, - ) -> Result { - let config = ClickhouseServerConfig::new( - // We can safely call unwrap here as this method is infallible - Utf8PathBuf::from_str(&settings.config_dir).unwrap(), - settings.node_id, - Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), - settings.listen_addr, - settings.keepers, - settings.remote_servers, - ); - - let replica_config = config + ) -> Result { + let replica_config = settings .generate_xml_file() .map_err(|e| ClickwardError::Failure { err: e })?; @@ -69,10 +57,10 @@ impl Clickward { settings: KeeperSettings, ) -> Result { let config = ClickhouseKeeperConfig::new( - Utf8PathBuf::from_str(&settings.config_dir).unwrap(), + settings.config_dir, settings.node_id, settings.keepers, - Utf8PathBuf::from_str(&settings.datastore_path).unwrap(), + settings.datastore_path, settings.listen_addr, ); diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 58221490fb..f266c4e8e5 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,7 +5,10 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use dropshot::{HttpError, HttpResponseCreated, Path, RequestContext, TypedBody}; +use clickhouse_admin_types::ServerSettings; +use dropshot::{ + HttpError, HttpResponseCreated, Path, RequestContext, TypedBody, +}; use std::sync::Arc; type ClickhouseApiDescription = dropshot::ApiDescription>; diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index 0e0ff968da..ac52280480 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -55,50 +55,62 @@ pub struct KeeperId(pub u64); )] pub struct ServerId(pub u64); -#[derive(Debug, Clone)] -pub struct ClickhouseServerConfig { +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct ServerSettings { + #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, - pub id: ServerId, + pub node_id: ServerId, + #[schemars(schema_with = "path_schema")] pub datastore_path: Utf8PathBuf, pub listen_addr: Ipv6Addr, - pub keepers: Vec, - pub servers: Vec, + pub keepers: Vec, + pub remote_servers: Vec, } -impl ClickhouseServerConfig { +impl ServerSettings { pub fn new( config_dir: Utf8PathBuf, - id: ServerId, + node_id: ServerId, datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, keepers: Vec, - servers: Vec, + remote_servers: Vec, ) -> Self { - let keepers = keepers + Self { + config_dir, + node_id, + datastore_path, + listen_addr, + keepers, + remote_servers, + } + } + + /// Generate a configuration file for a replica server node + pub fn generate_xml_file(&self) -> Result { + let logger = + LogConfig::new(self.datastore_path.clone(), NodeType::Server); + let macros = Macros::new(self.node_id); + + let keepers: Vec = self + .keepers .iter() .map(|host| KeeperNodeConfig::new(host.clone())) .collect(); - let servers = servers + let servers: Vec = self + .remote_servers .iter() .map(|host| ServerNodeConfig::new(host.clone())) .collect(); - Self { config_dir, id, datastore_path, listen_addr, keepers, servers } - } - - /// Generate a configuration file for a replica server node - pub fn generate_xml_file(&self) -> Result { - let logger = - LogConfig::new(self.datastore_path.clone(), NodeType::Server); - let macros = Macros::new(self.id); - let config = ReplicaConfig::new( logger, macros, self.listen_addr, - self.servers.clone(), - self.keepers.clone(), + servers.clone(), + keepers.clone(), self.datastore_path.clone(), ); @@ -174,7 +186,7 @@ mod tests { use camino_tempfile::Builder; use crate::{ - ClickhouseHost, ClickhouseKeeperConfig, ClickhouseServerConfig, + ClickhouseHost, ClickhouseKeeperConfig, ServerSettings, KeeperId, RaftServerSettings, ServerId, }; @@ -245,7 +257,7 @@ mod tests { ClickhouseHost::DomainName("ohai.com".to_string()), ]; - let config = ClickhouseServerConfig::new( + let config = ServerSettings::new( Utf8PathBuf::from(config_dir.path()), ServerId(1), Utf8PathBuf::from_str("./").unwrap(), diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index cda308cedc..0b407e00f2 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -275,10 +275,12 @@ "type": "object", "properties": { "config_dir": { - "type": "string" + "type": "string", + "format": "Utf8PathBuf" }, "datastore_path": { - "type": "string" + "type": "string", + "format": "Utf8PathBuf" }, "keepers": { "type": "array", @@ -514,10 +516,12 @@ "type": "object", "properties": { "config_dir": { - "type": "string" + "type": "string", + "format": "Utf8PathBuf" }, "datastore_path": { - "type": "string" + "type": "string", + "format": "Utf8PathBuf" }, "keepers": { "type": "array", From 3f483629f93a4d7c69e953a6a69ba360a22b16b7 Mon Sep 17 00:00:00 2001 From: karencfv Date: Mon, 2 Sep 2024 18:32:55 +1200 Subject: [PATCH 11/14] Simplify keeper api --- Cargo.lock | 1 - clickhouse-admin/api/Cargo.toml | 1 - clickhouse-admin/api/src/lib.rs | 22 +++------------ clickhouse-admin/src/clickward.rs | 15 +++-------- clickhouse-admin/src/http_entrypoints.rs | 2 +- clickhouse-admin/types/src/lib.rs | 34 +++++++++++++----------- openapi/clickhouse-admin.json | 18 ++++++------- 7 files changed, 34 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c25eda9d99..8666963ed8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,7 +1119,6 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "clickhouse-admin-api" version = "0.1.0" dependencies = [ - "camino", "clickhouse-admin-types", "dropshot 0.10.2-dev", "omicron-common", diff --git a/clickhouse-admin/api/Cargo.toml b/clickhouse-admin/api/Cargo.toml index e3bb96d001..a5d1dca202 100644 --- a/clickhouse-admin/api/Cargo.toml +++ b/clickhouse-admin/api/Cargo.toml @@ -8,7 +8,6 @@ license = "MPL-2.0" workspace = true [dependencies] -camino.workspace = true clickhouse-admin-types.workspace = true dropshot.workspace = true omicron-common.workspace = true diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index a5f1ff8924..8d7eadf73b 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -2,18 +2,14 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use camino::Utf8PathBuf; -use clickhouse_admin_types::config::{ - path_schema, KeeperConfig, RaftServerSettings, ReplicaConfig, -}; -use clickhouse_admin_types::{ServerSettings, KeeperId}; +use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; +use clickhouse_admin_types::{KeeperSettings, ServerSettings}; use dropshot::{ HttpError, HttpResponseCreated, Path, RequestContext, TypedBody, }; use omicron_common::api::external::Generation; use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::net::Ipv6Addr; +use serde::Deserialize; #[derive(Debug, Deserialize, JsonSchema)] pub struct GenerationNum { @@ -49,15 +45,3 @@ pub trait ClickhouseAdminApi { body: TypedBody, ) -> Result, HttpError>; } - -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct KeeperSettings { - #[schemars(schema_with = "path_schema")] - pub config_dir: Utf8PathBuf, - #[schemars(schema_with = "path_schema")] - pub datastore_path: Utf8PathBuf, - pub listen_addr: Ipv6Addr, - pub node_id: KeeperId, - pub keepers: Vec, -} diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index e2ba5f3524..d73fde94b8 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -2,9 +2,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use clickhouse_admin_api::KeeperSettings; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use clickhouse_admin_types::{ClickhouseKeeperConfig, ServerSettings}; +use clickhouse_admin_types::{KeeperSettings, ServerSettings}; use dropshot::HttpError; use slog_error_chain::{InlineErrorChain, SlogInlineError}; @@ -44,7 +43,7 @@ impl Clickward { pub fn generate_server_config( &self, settings: ServerSettings, - ) -> Result { + ) -> Result { let replica_config = settings .generate_xml_file() .map_err(|e| ClickwardError::Failure { err: e })?; @@ -56,15 +55,7 @@ impl Clickward { &self, settings: KeeperSettings, ) -> Result { - let config = ClickhouseKeeperConfig::new( - settings.config_dir, - settings.node_id, - settings.keepers, - settings.datastore_path, - settings.listen_addr, - ); - - let keeper_config = config + let keeper_config = settings .generate_xml_file() .map_err(|e| ClickwardError::Failure { err: e })?; diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index f266c4e8e5..782b2b4790 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,7 +5,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use clickhouse_admin_types::ServerSettings; +use clickhouse_admin_types::{KeeperSettings, ServerSettings}; use dropshot::{ HttpError, HttpResponseCreated, Path, RequestContext, TypedBody, }; diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index ac52280480..d5e401c66a 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -126,41 +126,43 @@ impl ServerSettings { #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] -pub struct ClickhouseKeeperConfig { +pub struct KeeperSettings { #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, - pub id: KeeperId, - pub raft_servers: Vec, + pub node_id: KeeperId, + pub raft_servers: Vec, #[schemars(schema_with = "path_schema")] pub datastore_path: Utf8PathBuf, pub listen_addr: Ipv6Addr, } -impl ClickhouseKeeperConfig { +impl KeeperSettings { pub fn new( config_dir: Utf8PathBuf, - id: KeeperId, + node_id: KeeperId, raft_servers: Vec, datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, ) -> Self { - let raft_servers = raft_servers - .iter() - .map(|settings| RaftServerConfig::new(settings.clone())) - .collect(); - - Self { config_dir, id, raft_servers, datastore_path, listen_addr } + Self { config_dir, node_id, raft_servers, datastore_path, listen_addr } } /// Generate a configuration file for a keeper node pub fn generate_xml_file(&self) -> Result { let logger = LogConfig::new(self.datastore_path.clone(), NodeType::Keeper); - let raft_config = RaftServers::new(self.raft_servers.clone()); + + let raft_servers = self + .raft_servers + .iter() + .map(|settings| RaftServerConfig::new(settings.clone())) + .collect(); + let raft_config = RaftServers::new(raft_servers); + let config = KeeperConfig::new( logger, self.listen_addr, - self.id, + self.node_id, self.datastore_path.clone(), raft_config, ); @@ -186,8 +188,8 @@ mod tests { use camino_tempfile::Builder; use crate::{ - ClickhouseHost, ClickhouseKeeperConfig, ServerSettings, - KeeperId, RaftServerSettings, ServerId, + ClickhouseHost, KeeperId, KeeperSettings, RaftServerSettings, ServerId, + ServerSettings, }; #[test] @@ -217,7 +219,7 @@ mod tests { }, ]; - let config = ClickhouseKeeperConfig::new( + let config = KeeperSettings::new( Utf8PathBuf::from(config_dir.path()), KeeperId(1), keepers, diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index 0b407e00f2..c1342cbfec 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -282,26 +282,26 @@ "type": "string", "format": "Utf8PathBuf" }, - "keepers": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RaftServerSettings" - } + "id": { + "$ref": "#/components/schemas/KeeperId" }, "listen_addr": { "type": "string", "format": "ipv6" }, - "node_id": { - "$ref": "#/components/schemas/KeeperId" + "raft_servers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RaftServerSettings" + } } }, "required": [ "config_dir", "datastore_path", - "keepers", + "id", "listen_addr", - "node_id" + "raft_servers" ] }, "LogConfig": { From 2f7f8bda66f37091e5b18ad281222c5aa062fef2 Mon Sep 17 00:00:00 2001 From: karencfv Date: Mon, 2 Sep 2024 19:07:30 +1200 Subject: [PATCH 12/14] Add some documentation --- clickhouse-admin/src/http_entrypoints.rs | 4 +- clickhouse-admin/types/src/config.rs | 18 +++++ clickhouse-admin/types/src/lib.rs | 11 +++ openapi/clickhouse-admin.json | 94 ++++++++++++++++++++---- 4 files changed, 112 insertions(+), 15 deletions(-) diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 782b2b4790..fb3ce733fc 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -31,7 +31,7 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { let ctx = rqctx.context(); let server_settings = body.into_inner(); let output = ctx.clickward().generate_server_config(server_settings)?; - // TODO: Do something with the generation number + // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something with the generation number println!("{path:?}"); Ok(HttpResponseCreated(output)) } @@ -44,7 +44,7 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { let ctx = rqctx.context(); let keeper_settings = body.into_inner(); let output = ctx.clickward().generate_keeper_config(keeper_settings)?; - // TODO: Do something with the generation number + // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something with the generation number println!("{path:?}"); Ok(HttpResponseCreated(output)) } diff --git a/clickhouse-admin/types/src/config.rs b/clickhouse-admin/types/src/config.rs index a31295834a..f0f04a8aa3 100644 --- a/clickhouse-admin/types/src/config.rs +++ b/clickhouse-admin/types/src/config.rs @@ -29,14 +29,24 @@ pub fn path_schema(gen: &mut SchemaGenerator) -> Schema { /// Configuration for a ClickHouse replica server #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] pub struct ReplicaConfig { + /// Logging settings pub logger: LogConfig, + /// Parameter substitutions for replicated tables pub macros: Macros, + /// Address the server is listening on pub listen_host: Ipv6Addr, + /// Port for HTTP connections pub http_port: u16, + /// Port for TCP connections pub tcp_port: u16, + /// Port for interserver HTTP connections pub interserver_http_port: u16, + /// Configuration of clusters used by the Distributed table engine and bythe cluster + /// table function pub remote_servers: RemoteServers, + /// Contains settings that allow ClickHouse servers to interact with a Keeper cluster pub keepers: KeeperConfigsForReplica, + /// Directory for all files generated by ClickHouse itself #[schemars(schema_with = "path_schema")] pub data_path: Utf8PathBuf, } @@ -444,15 +454,23 @@ impl RaftServerConfig { /// Configuration for a ClickHouse keeper #[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Serialize, Deserialize)] pub struct KeeperConfig { + /// Logging settings pub logger: LogConfig, + /// Address the keeper is listening on pub listen_host: Ipv6Addr, + /// Port for TCP connections pub tcp_port: u16, + /// Unique ID for this keeper node pub server_id: KeeperId, + /// Directory for coordination logs #[schemars(schema_with = "path_schema")] pub log_storage_path: Utf8PathBuf, + /// Directory for coordination snapshot storage #[schemars(schema_with = "path_schema")] pub snapshot_storage_path: Utf8PathBuf, + /// Internal coordination settings pub coordination_settings: KeeperCoordinationSettings, + /// Settings for each server in the keeper cluster pub raft_config: RaftServers, } diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index d5e401c66a..555fbc6d31 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -58,13 +58,19 @@ pub struct ServerId(pub u64); #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct ServerSettings { + /// Directory for the generated server configuration XML file #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, + /// Unique ID of the server pub node_id: ServerId, + /// Directory for all files generated by ClickHouse itself #[schemars(schema_with = "path_schema")] pub datastore_path: Utf8PathBuf, + /// Address the server is listening on pub listen_addr: Ipv6Addr, + /// Addresses for each of the individual nodes in the Keeper cluster pub keepers: Vec, + /// Addresses for each of the individual replica servers pub remote_servers: Vec, } @@ -127,12 +133,17 @@ impl ServerSettings { #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct KeeperSettings { + /// Directory for the generated keeper configuration XML file #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, + /// Unique ID of the keeper pub node_id: KeeperId, + /// ID and host of each server in the keeper cluster pub raft_servers: Vec, + /// Directory for all files generated by ClickHouse itself #[schemars(schema_with = "path_schema")] pub datastore_path: Utf8PathBuf, + /// Address the keeper is listening on pub listen_addr: Ipv6Addr, } diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index c1342cbfec..5afe4b906d 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -171,30 +171,54 @@ "type": "object", "properties": { "coordination_settings": { - "$ref": "#/components/schemas/KeeperCoordinationSettings" + "description": "Internal coordination settings", + "allOf": [ + { + "$ref": "#/components/schemas/KeeperCoordinationSettings" + } + ] }, "listen_host": { + "description": "Address the keeper is listening on", "type": "string", "format": "ipv6" }, "log_storage_path": { + "description": "Directory for coordination logs", "type": "string", "format": "Utf8PathBuf" }, "logger": { - "$ref": "#/components/schemas/LogConfig" + "description": "Logging settings", + "allOf": [ + { + "$ref": "#/components/schemas/LogConfig" + } + ] }, "raft_config": { - "$ref": "#/components/schemas/RaftServers" + "description": "Settings for each server in the keeper cluster", + "allOf": [ + { + "$ref": "#/components/schemas/RaftServers" + } + ] }, "server_id": { - "$ref": "#/components/schemas/KeeperId" + "description": "Unique ID for this keeper node", + "allOf": [ + { + "$ref": "#/components/schemas/KeeperId" + } + ] }, "snapshot_storage_path": { + "description": "Directory for coordination snapshot storage", "type": "string", "format": "Utf8PathBuf" }, "tcp_port": { + "description": "Port for TCP connections", "type": "integer", "format": "uint16", "minimum": 0 @@ -275,21 +299,30 @@ "type": "object", "properties": { "config_dir": { + "description": "Directory for the generated keeper configuration XML file", "type": "string", "format": "Utf8PathBuf" }, "datastore_path": { + "description": "Directory for all files generated by ClickHouse itself", "type": "string", "format": "Utf8PathBuf" }, - "id": { - "$ref": "#/components/schemas/KeeperId" - }, "listen_addr": { + "description": "Address the keeper is listening on", "type": "string", "format": "ipv6" }, + "node_id": { + "description": "Unique ID of the keeper", + "allOf": [ + { + "$ref": "#/components/schemas/KeeperId" + } + ] + }, "raft_servers": { + "description": "ID and host of each server in the keeper cluster", "type": "array", "items": { "$ref": "#/components/schemas/RaftServerSettings" @@ -299,8 +332,8 @@ "required": [ "config_dir", "datastore_path", - "id", "listen_addr", + "node_id", "raft_servers" ] }, @@ -442,36 +475,61 @@ "type": "object", "properties": { "data_path": { + "description": "Directory for all files generated by ClickHouse itself", "type": "string", "format": "Utf8PathBuf" }, "http_port": { + "description": "Port for HTTP connections", "type": "integer", "format": "uint16", "minimum": 0 }, "interserver_http_port": { + "description": "Port for interserver HTTP connections", "type": "integer", "format": "uint16", "minimum": 0 }, "keepers": { - "$ref": "#/components/schemas/KeeperConfigsForReplica" + "description": "Contains settings that allow ClickHouse servers to interact with a Keeper cluster", + "allOf": [ + { + "$ref": "#/components/schemas/KeeperConfigsForReplica" + } + ] }, "listen_host": { + "description": "Address the server is listening on", "type": "string", "format": "ipv6" }, "logger": { - "$ref": "#/components/schemas/LogConfig" + "description": "Logging settings", + "allOf": [ + { + "$ref": "#/components/schemas/LogConfig" + } + ] }, "macros": { - "$ref": "#/components/schemas/Macros" + "description": "Parameter substitutions for replicated tables", + "allOf": [ + { + "$ref": "#/components/schemas/Macros" + } + ] }, "remote_servers": { - "$ref": "#/components/schemas/RemoteServers" + "description": "Configuration of clusters used by the Distributed table engine and bythe cluster table function", + "allOf": [ + { + "$ref": "#/components/schemas/RemoteServers" + } + ] }, "tcp_port": { + "description": "Port for TCP connections", "type": "integer", "format": "uint16", "minimum": 0 @@ -516,27 +574,37 @@ "type": "object", "properties": { "config_dir": { + "description": "Directory for the generated server configuration XML file", "type": "string", "format": "Utf8PathBuf" }, "datastore_path": { + "description": "Directory for all files generated by ClickHouse itself", "type": "string", "format": "Utf8PathBuf" }, "keepers": { + "description": "Addresses for each of the individual nodes in the Keeper cluster", "type": "array", "items": { "$ref": "#/components/schemas/ClickhouseHost" } }, "listen_addr": { + "description": "Address the server is listening on", "type": "string", "format": "ipv6" }, "node_id": { - "$ref": "#/components/schemas/ServerId" + "description": "Unique ID of the server", + "allOf": [ + { + "$ref": "#/components/schemas/ServerId" + } + ] }, "remote_servers": { + "description": "Addresses for each of the individual replica servers", "type": "array", "items": { "$ref": "#/components/schemas/ClickhouseHost" From aa1375fc9587a51122811431973c4e9db58e23cd Mon Sep 17 00:00:00 2001 From: karencfv Date: Thu, 5 Sep 2024 11:29:24 +1200 Subject: [PATCH 13/14] Address comments --- clickhouse-admin/api/src/lib.rs | 28 ++++--- clickhouse-admin/src/http_entrypoints.rs | 25 +++--- clickhouse-admin/types/src/lib.rs | 2 + openapi/clickhouse-admin.json | 98 ++++++++++++++++-------- 4 files changed, 95 insertions(+), 58 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index 8d7eadf73b..b19a8938b4 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -5,16 +5,26 @@ use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; use clickhouse_admin_types::{KeeperSettings, ServerSettings}; use dropshot::{ - HttpError, HttpResponseCreated, Path, RequestContext, TypedBody, + HttpError, HttpResponseCreated, RequestContext, TypedBody, }; use omicron_common::api::external::Generation; use schemars::JsonSchema; use serde::Deserialize; #[derive(Debug, Deserialize, JsonSchema)] -pub struct GenerationNum { +pub struct ServerConfigurableSettings { /// A unique identifier for the configuration generation. pub generation: Generation, + /// Configurable settings for a ClickHouse replica server node. + pub settings: ServerSettings, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct KeeperConfigurableSettings { + /// A unique identifier for the configuration generation. + pub generation: Generation, + /// Configurable settings for a ClickHouse keeper node. + pub settings: KeeperSettings, } #[dropshot::api_description] @@ -24,24 +34,22 @@ pub trait ClickhouseAdminApi { /// Generate a ClickHouse configuration file for a server node on a specified /// directory. #[endpoint { - method = POST, - path = "/node/server/generate-config/{generation}", + method = PUT, + path = "/server/config", }] async fn generate_server_config( rqctx: RequestContext, - path: Path, - body: TypedBody, + body: TypedBody, ) -> Result, HttpError>; /// Generate a ClickHouse configuration file for a keeper node on a specified /// directory. #[endpoint { - method = POST, - path = "/node/keeper/generate-config/{generation}", + method = PUT, + path = "/keeper/config", }] async fn generate_keeper_config( rqctx: RequestContext, - path: Path, - body: TypedBody, + body: TypedBody, ) -> Result, HttpError>; } diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index fb3ce733fc..298d4400b3 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,9 +5,8 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use clickhouse_admin_types::{KeeperSettings, ServerSettings}; use dropshot::{ - HttpError, HttpResponseCreated, Path, RequestContext, TypedBody, + HttpError, HttpResponseCreated, RequestContext, TypedBody, }; use std::sync::Arc; @@ -25,27 +24,25 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { async fn generate_server_config( rqctx: RequestContext, - path: Path, - body: TypedBody, + body: TypedBody, ) -> Result, HttpError> { let ctx = rqctx.context(); - let server_settings = body.into_inner(); - let output = ctx.clickward().generate_server_config(server_settings)?; - // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something with the generation number - println!("{path:?}"); + let replica_server = body.into_inner(); + // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something + // with the generation number `replica_server.generation` + let output = ctx.clickward().generate_server_config(replica_server.settings)?; Ok(HttpResponseCreated(output)) } async fn generate_keeper_config( rqctx: RequestContext, - path: Path, - body: TypedBody, + body: TypedBody, ) -> Result, HttpError> { let ctx = rqctx.context(); - let keeper_settings = body.into_inner(); - let output = ctx.clickward().generate_keeper_config(keeper_settings)?; - // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something with the generation number - println!("{path:?}"); + let keeper = body.into_inner(); + // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something + // with the generation number `keeper.generation` + let output = ctx.clickward().generate_keeper_config(keeper.settings)?; Ok(HttpResponseCreated(output)) } } diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index 555fbc6d31..034e90dbc3 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -55,6 +55,7 @@ pub struct KeeperId(pub u64); )] pub struct ServerId(pub u64); +/// Configurable settings for a ClickHouse replica server node. #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct ServerSettings { @@ -130,6 +131,7 @@ impl ServerSettings { } } + /// Configurable settings for a ClickHouse keeper node. #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct KeeperSettings { diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index 5afe4b906d..0dc7eba796 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -10,27 +10,16 @@ "version": "0.0.1" }, "paths": { - "/node/keeper/generate-config/{generation}": { - "post": { + "/keeper/config": { + "put": { "summary": "Generate a ClickHouse configuration file for a keeper node on a specified", "description": "directory.", "operationId": "generate_keeper_config", - "parameters": [ - { - "in": "path", - "name": "generation", - "description": "A unique identifier for the configuration generation.", - "required": true, - "schema": { - "$ref": "#/components/schemas/Generation" - } - } - ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/KeeperSettings" + "$ref": "#/components/schemas/KeeperConfigurableSettings" } } }, @@ -56,27 +45,16 @@ } } }, - "/node/server/generate-config/{generation}": { - "post": { + "/server/config": { + "put": { "summary": "Generate a ClickHouse configuration file for a server node on a specified", "description": "directory.", "operationId": "generate_server_config", - "parameters": [ - { - "in": "path", - "name": "generation", - "description": "A unique identifier for the configuration generation.", - "required": true, - "schema": { - "$ref": "#/components/schemas/Generation" - } - } - ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServerSettings" + "$ref": "#/components/schemas/ServerConfigurableSettings" } } }, @@ -166,6 +144,12 @@ "request_id" ] }, + "Generation": { + "description": "Generation numbers stored in the database, used for optimistic concurrency control", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, "KeeperConfig": { "description": "Configuration for a ClickHouse keeper", "type": "object", @@ -249,6 +233,31 @@ "nodes" ] }, + "KeeperConfigurableSettings": { + "type": "object", + "properties": { + "generation": { + "description": "A unique identifier for the configuration generation.", + "allOf": [ + { + "$ref": "#/components/schemas/Generation" + } + ] + }, + "settings": { + "description": "Configurable settings for a ClickHouse keeper node.", + "allOf": [ + { + "$ref": "#/components/schemas/KeeperSettings" + } + ] + } + }, + "required": [ + "generation", + "settings" + ] + }, "KeeperCoordinationSettings": { "type": "object", "properties": { @@ -296,6 +305,7 @@ ] }, "KeeperSettings": { + "description": "Configurable settings for a ClickHouse keeper node.", "type": "object", "properties": { "config_dir": { @@ -547,6 +557,31 @@ "tcp_port" ] }, + "ServerConfigurableSettings": { + "type": "object", + "properties": { + "generation": { + "description": "A unique identifier for the configuration generation.", + "allOf": [ + { + "$ref": "#/components/schemas/Generation" + } + ] + }, + "settings": { + "description": "Configurable settings for a ClickHouse replica server node.", + "allOf": [ + { + "$ref": "#/components/schemas/ServerSettings" + } + ] + } + }, + "required": [ + "generation", + "settings" + ] + }, "ServerId": { "description": "A unique ID for a Clickhouse Server", "type": "integer", @@ -571,6 +606,7 @@ ] }, "ServerSettings": { + "description": "Configurable settings for a ClickHouse replica server node.", "type": "object", "properties": { "config_dir": { @@ -619,12 +655,6 @@ "node_id", "remote_servers" ] - }, - "Generation": { - "description": "Generation numbers stored in the database, used for optimistic concurrency control", - "type": "integer", - "format": "uint64", - "minimum": 0 } }, "responses": { From 48f8cf9eaf262a8bb8b7f31e3305d1d20093f213 Mon Sep 17 00:00:00 2001 From: karencfv Date: Thu, 5 Sep 2024 11:58:17 +1200 Subject: [PATCH 14/14] clean up --- clickhouse-admin/api/src/lib.rs | 4 +-- clickhouse-admin/src/clickward.rs | 2 +- clickhouse-admin/src/http_entrypoints.rs | 7 +++-- clickhouse-admin/types/src/lib.rs | 22 +++++++-------- openapi/clickhouse-admin.json | 34 ++++++++++++------------ 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/clickhouse-admin/api/src/lib.rs b/clickhouse-admin/api/src/lib.rs index b19a8938b4..a63499a7c5 100644 --- a/clickhouse-admin/api/src/lib.rs +++ b/clickhouse-admin/api/src/lib.rs @@ -4,9 +4,7 @@ use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; use clickhouse_admin_types::{KeeperSettings, ServerSettings}; -use dropshot::{ - HttpError, HttpResponseCreated, RequestContext, TypedBody, -}; +use dropshot::{HttpError, HttpResponseCreated, RequestContext, TypedBody}; use omicron_common::api::external::Generation; use schemars::JsonSchema; use serde::Deserialize; diff --git a/clickhouse-admin/src/clickward.rs b/clickhouse-admin/src/clickward.rs index d73fde94b8..5202b9b090 100644 --- a/clickhouse-admin/src/clickward.rs +++ b/clickhouse-admin/src/clickward.rs @@ -9,7 +9,7 @@ use slog_error_chain::{InlineErrorChain, SlogInlineError}; #[derive(Debug, thiserror::Error, SlogInlineError)] pub enum ClickwardError { - #[error("clickward failure")] + #[error("clickward XML generation failure")] Failure { #[source] err: anyhow::Error, diff --git a/clickhouse-admin/src/http_entrypoints.rs b/clickhouse-admin/src/http_entrypoints.rs index 298d4400b3..ddeb35916f 100644 --- a/clickhouse-admin/src/http_entrypoints.rs +++ b/clickhouse-admin/src/http_entrypoints.rs @@ -5,9 +5,7 @@ use crate::context::ServerContext; use clickhouse_admin_api::*; use clickhouse_admin_types::config::{KeeperConfig, ReplicaConfig}; -use dropshot::{ - HttpError, HttpResponseCreated, RequestContext, TypedBody, -}; +use dropshot::{HttpError, HttpResponseCreated, RequestContext, TypedBody}; use std::sync::Arc; type ClickhouseApiDescription = dropshot::ApiDescription>; @@ -30,7 +28,8 @@ impl ClickhouseAdminApi for ClickhouseAdminImpl { let replica_server = body.into_inner(); // TODO(https://github.com/oxidecomputer/omicron/issues/5999): Do something // with the generation number `replica_server.generation` - let output = ctx.clickward().generate_server_config(replica_server.settings)?; + let output = + ctx.clickward().generate_server_config(replica_server.settings)?; Ok(HttpResponseCreated(output)) } diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index 034e90dbc3..4650d344ed 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -62,8 +62,8 @@ pub struct ServerSettings { /// Directory for the generated server configuration XML file #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, - /// Unique ID of the server - pub node_id: ServerId, + /// Unique ID of the server node + pub id: ServerId, /// Directory for all files generated by ClickHouse itself #[schemars(schema_with = "path_schema")] pub datastore_path: Utf8PathBuf, @@ -78,7 +78,7 @@ pub struct ServerSettings { impl ServerSettings { pub fn new( config_dir: Utf8PathBuf, - node_id: ServerId, + id: ServerId, datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, keepers: Vec, @@ -86,7 +86,7 @@ impl ServerSettings { ) -> Self { Self { config_dir, - node_id, + id, datastore_path, listen_addr, keepers, @@ -98,7 +98,7 @@ impl ServerSettings { pub fn generate_xml_file(&self) -> Result { let logger = LogConfig::new(self.datastore_path.clone(), NodeType::Server); - let macros = Macros::new(self.node_id); + let macros = Macros::new(self.id); let keepers: Vec = self .keepers @@ -131,15 +131,15 @@ impl ServerSettings { } } - /// Configurable settings for a ClickHouse keeper node. +/// Configurable settings for a ClickHouse keeper node. #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct KeeperSettings { /// Directory for the generated keeper configuration XML file #[schemars(schema_with = "path_schema")] pub config_dir: Utf8PathBuf, - /// Unique ID of the keeper - pub node_id: KeeperId, + /// Unique ID of the keeper node + pub id: KeeperId, /// ID and host of each server in the keeper cluster pub raft_servers: Vec, /// Directory for all files generated by ClickHouse itself @@ -152,12 +152,12 @@ pub struct KeeperSettings { impl KeeperSettings { pub fn new( config_dir: Utf8PathBuf, - node_id: KeeperId, + id: KeeperId, raft_servers: Vec, datastore_path: Utf8PathBuf, listen_addr: Ipv6Addr, ) -> Self { - Self { config_dir, node_id, raft_servers, datastore_path, listen_addr } + Self { config_dir, id, raft_servers, datastore_path, listen_addr } } /// Generate a configuration file for a keeper node @@ -175,7 +175,7 @@ impl KeeperSettings { let config = KeeperConfig::new( logger, self.listen_addr, - self.node_id, + self.id, self.datastore_path.clone(), raft_config, ); diff --git a/openapi/clickhouse-admin.json b/openapi/clickhouse-admin.json index 0dc7eba796..33a233de76 100644 --- a/openapi/clickhouse-admin.json +++ b/openapi/clickhouse-admin.json @@ -318,19 +318,19 @@ "type": "string", "format": "Utf8PathBuf" }, - "listen_addr": { - "description": "Address the keeper is listening on", - "type": "string", - "format": "ipv6" - }, - "node_id": { - "description": "Unique ID of the keeper", + "id": { + "description": "Unique ID of the keeper node", "allOf": [ { "$ref": "#/components/schemas/KeeperId" } ] }, + "listen_addr": { + "description": "Address the keeper is listening on", + "type": "string", + "format": "ipv6" + }, "raft_servers": { "description": "ID and host of each server in the keeper cluster", "type": "array", @@ -342,8 +342,8 @@ "required": [ "config_dir", "datastore_path", + "id", "listen_addr", - "node_id", "raft_servers" ] }, @@ -619,6 +619,14 @@ "type": "string", "format": "Utf8PathBuf" }, + "id": { + "description": "Unique ID of the server node", + "allOf": [ + { + "$ref": "#/components/schemas/ServerId" + } + ] + }, "keepers": { "description": "Addresses for each of the individual nodes in the Keeper cluster", "type": "array", @@ -631,14 +639,6 @@ "type": "string", "format": "ipv6" }, - "node_id": { - "description": "Unique ID of the server", - "allOf": [ - { - "$ref": "#/components/schemas/ServerId" - } - ] - }, "remote_servers": { "description": "Addresses for each of the individual replica servers", "type": "array", @@ -650,9 +650,9 @@ "required": [ "config_dir", "datastore_path", + "id", "keepers", "listen_addr", - "node_id", "remote_servers" ] }