diff --git a/bin/nanocl/src/commands/node.rs b/bin/nanocl/src/commands/node.rs index ca54f53d441ee64a9784b8966a9b7397f6208840..0fb6ad2fe4146f2ee3593e44b1406acf38240ab5 100644 --- a/bin/nanocl/src/commands/node.rs +++ b/bin/nanocl/src/commands/node.rs @@ -1,3 +1,4 @@ +use bollard_next::models::RestartPolicyNameEnum::NO; use nanocl_error::io::IoResult; use crate::{ @@ -5,7 +6,12 @@ use crate::{ models::{NodeArg, NodeCommand, NodeRow}, }; -use super::{GenericCommand, GenericCommandLs}; +use super::{GenericCommand, GenericCommandLs, GenericCommandStop}; + +use nanocld_client::{ + NanocldClient, +}; +use crate::models::{CargoArg, GenericJoinOpts}; impl GenericCommand for NodeArg { fn object_name() -> &'static str { @@ -28,5 +34,21 @@ pub async fn exec_node(cli_conf: &CliConfig, args: &NodeArg) -> IoResult<()> { let client = &cli_conf.client; match &args.command { NodeCommand::List(opts) => NodeArg::exec_ls(client, args, opts).await, + NodeCommand::Join(opts) => NodeArg::exec_join(client, opts).await, + } +} + +trait JoinCluster { + async fn exec_join( + client: &NanocldClient, + opts: &GenericJoinOpts, + ) -> IoResult<()> + { + println!("client url: {}", client.url); + println!("master ip: {}", opts.master_ip); + println!("exec_join!"); + Ok(()) } } + +impl JoinCluster for NodeArg {} \ No newline at end of file diff --git a/bin/nanocl/src/models/generic.rs b/bin/nanocl/src/models/generic.rs index 8c4f95a00d2b25dba2a30543453f0d0892a18569..88cfccae892126539c3169a3ab923f11722b2179 100644 --- a/bin/nanocl/src/models/generic.rs +++ b/bin/nanocl/src/models/generic.rs @@ -102,3 +102,9 @@ pub struct GenericInspectOpts { /// Key or Name of the object to inspect pub key: String, } + +/// Generic join options for the join command +#[derive(Clone, Parser)] +pub struct GenericJoinOpts { + pub master_ip: String, +} \ No newline at end of file diff --git a/bin/nanocl/src/models/node.rs b/bin/nanocl/src/models/node.rs index 9f5ee69537c71fb91f141ffc44ba18c65ac61ab4..dd44d2618bb8db74faf157995fe4eb3c0223e7b9 100644 --- a/bin/nanocl/src/models/node.rs +++ b/bin/nanocl/src/models/node.rs @@ -2,8 +2,7 @@ use clap::{Parser, Subcommand}; use nanocld_client::stubs::node::Node; use tabled::Tabled; -use super::GenericListOpts; - +use super::{GenericListOpts, GenericJoinOpts}; /// `nanocl node` available arguments #[derive(Clone, Parser)] pub struct NodeArg { @@ -17,6 +16,9 @@ pub enum NodeCommand { /// List nodes #[clap(alias = "ls")] List(GenericListOpts), + /// Join node to a cluster + #[clap(alias = "join")] + Join(GenericJoinOpts), } /// A row of the node table @@ -25,26 +27,39 @@ pub enum NodeCommand { pub struct NodeRow { /// Name of the node pub name: String, + /// The role of the node + pub role: String, /// IP address of the node + #[tabled(rename = "IP ADDRESS")] pub ip_address: String, /// Endpoint of the node pub endpoint: String, + /// The endpoint of the master node + #[tabled(rename = "MASTER ENDPOINT")] + pub master_endpoint: String, /// Version of the node pub version: String, #[tabled(rename = "CREATED AT")] created_at: String, + #[tabled(rename = "UPDATED AT")] + updated_at: String, + /// Node status + pub status: String, } /// Convert a Node to a NodeRow impl From for NodeRow { fn from(node: Node) -> Self { - let created_at = node.created_at; Self { name: node.name, + role: node.role, ip_address: node.ip_address.to_string(), endpoint: node.endpoint, + master_endpoint: node.master_endpoint, version: node.version, - created_at, + created_at: node.created_at, + updated_at: node.updated_at, + status: node.status, } } } diff --git a/bin/nanocld/migrations/2022-08-04-214925_nodes/up.sql b/bin/nanocld/migrations/2022-08-04-214925_nodes/up.sql index fb0f0aa47841c2dea89fdd6115d58737f9d45083..4c34afe4bc846928e2eb2c82d1c86108a284c56d 100644 --- a/bin/nanocld/migrations/2022-08-04-214925_nodes/up.sql +++ b/bin/nanocld/migrations/2022-08-04-214925_nodes/up.sql @@ -7,7 +7,8 @@ CREATE TABLE IF NOT EXISTS "nodes" ( "endpoint" VARCHAR NOT NULL, "master_endpoint" VARCHAR NOT NULL, "version" VARCHAR NOT NULL, - "metadata" TEXT -- 使用 TEXT 替代 JSONB + "metadata" TEXT, -- 使用 TEXT 替代 JSONB + "status" TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS "node_groups" ( @@ -27,6 +28,6 @@ CREATE INDEX "nodes_ip_address_idx" ON "nodes" ("ip_address"); CREATE INDEX "nodes_endpoint_idx" ON "nodes" ("endpoint"); CREATE INDEX "nodes_master_endpoint_idx" ON "nodes" ("master_endpoint"); CREATE INDEX "nodes_version_idx" ON "nodes" ("version"); - +CREATE INDEX "nodes_status_idx" ON "nodes" ("status"); -- 删除不兼容的 GIN 索引,改为普通 TEXT 索引 CREATE INDEX "nodes_metadata_idx" ON "nodes" ("metadata"); diff --git a/bin/nanocld/src/models/node.rs b/bin/nanocld/src/models/node.rs index b8fca9d4ba647836d0b6975acb9b0e03aea49e16..af8b6007fc649902fb739e22d3f3d6465a303f5e 100644 --- a/bin/nanocld/src/models/node.rs +++ b/bin/nanocld/src/models/node.rs @@ -31,4 +31,6 @@ pub struct NodeDb { /// User defined metadata #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option, + /// Node status + pub status: String, } diff --git a/bin/nanocld/src/repositories/node.rs b/bin/nanocld/src/repositories/node.rs index f987e7cdfd567eb4b31de8ee4a8be9a73c14a3ea..b401204937a6fb22466c2ee96b1eda7e151521f5 100644 --- a/bin/nanocld/src/repositories/node.rs +++ b/bin/nanocld/src/repositories/node.rs @@ -101,6 +101,7 @@ impl NodeDb { updated_at: chrono::Utc::now().naive_utc().format("%Y-%m-%d %H:%M:%S").to_string(), version: vars::VERSION.to_owned(), metadata: None, + status: "Ready".parse().unwrap(), }; NodeDb::create_if_not_exists(&node, &state.inner.pool).await?; Ok(()) diff --git a/bin/nanocld/src/schema.rs b/bin/nanocld/src/schema.rs index 14354dc0cbf950ecd89ee029a4f2a24747a16342..861128c000717f8ac828937ebb3888c00defce66 100644 --- a/bin/nanocld/src/schema.rs +++ b/bin/nanocld/src/schema.rs @@ -84,6 +84,7 @@ diesel::table! { master_endpoint -> Text, version -> Text, metadata -> Nullable, + status -> Text, } } diff --git a/crates/nanocl_stubs/src/node.rs b/crates/nanocl_stubs/src/node.rs index d3bf58373bde4fde47728e3c9284d5d0f659a680..3a4bf7cb3899cc57f97657969929f7769e582093 100644 --- a/crates/nanocl_stubs/src/node.rs +++ b/crates/nanocl_stubs/src/node.rs @@ -9,16 +9,27 @@ use serde::{Deserialize, Serialize}; pub struct Node { /// The name of the node pub name: String, + /// The role of the node + pub role: String, /// The created at date pub created_at: String, + /// The updated date + pub updated_at: String, /// The ip address of the node #[cfg_attr(feature = "utoipa", schema(value_type = String))] pub ip_address: String, /// Endpoint to connect to the node pub endpoint: String, + /// The endpoint of the master node + pub master_endpoint: String, /// Version of the node pub version: String, /// User defined metadata #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option, + /// Node status + pub status: String, } + + +