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 e8bda671f..7a690e04a 100644 --- a/bin/nanocld/migrations/2022-08-04-214925_nodes/up.sql +++ b/bin/nanocld/migrations/2022-08-04-214925_nodes/up.sql @@ -1,7 +1,8 @@ -- Your SQL goes here CREATE TABLE IF NOT EXISTS "nodes" ( "name" VARCHAR NOT NULL UNIQUE PRIMARY KEY, - "ip_address" VARCHAR NOT NULL UNIQUE + "ip_address" VARCHAR NOT NULL UNIQUE, + "created_at" TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS "node_groups" ( diff --git a/bin/nanocld/src/models/node.rs b/bin/nanocld/src/models/node.rs index 6c849e9f2..f47fa8d2d 100644 --- a/bin/nanocld/src/models/node.rs +++ b/bin/nanocld/src/models/node.rs @@ -1,16 +1,7 @@ -use std::sync::Arc; - use diesel::prelude::*; -use ntex::rt::JoinHandle; use serde::{Serialize, Deserialize}; -use nanocl_error::io::{IoError, IoResult}; - -use nanocl_stubs::generic::GenericFilter; - -use crate::{utils, schema::nodes}; - -use super::{Pool, Repository}; +use crate::schema::nodes; /// This structure represent a node in the database. /// A node is a machine that is connected to nanocl network. @@ -25,61 +16,6 @@ pub struct NodeDb { pub name: String, /// The ip address of the node pub ip_address: String, -} - -impl Repository for NodeDb { - type Table = nodes::table; - type Item = NodeDb; - type UpdateItem = NodeDb; - - fn find_one( - filter: &GenericFilter, - pool: &Pool, - ) -> JoinHandle> { - log::trace!("NodeDb::find_one: {filter:?}"); - // let r#where = filter.r#where.to_owned().unwrap_or_default(); - let query = nodes::dsl::nodes.into_boxed(); - let pool = Arc::clone(pool); - ntex::rt::spawn_blocking(move || { - let mut conn = utils::store::get_pool_conn(&pool)?; - let item = query - .get_result::(&mut conn) - .map_err(Self::map_err_context)?; - Ok::<_, IoError>(item) - }) - } - - fn find( - filter: &GenericFilter, - pool: &Pool, - ) -> JoinHandle>> { - log::trace!("NodeDb::find: {filter:?}"); - // let r#where = filter.r#where.to_owned().unwrap_or_default(); - let mut query = nodes::dsl::nodes.into_boxed(); - let limit = filter.limit.unwrap_or(100); - query = query.limit(limit as i64); - if let Some(offset) = filter.offset { - query = query.offset(offset as i64); - } - let pool = Arc::clone(pool); - ntex::rt::spawn_blocking(move || { - let mut conn = utils::store::get_pool_conn(&pool)?; - let items = query - .get_results::(&mut conn) - .map_err(Self::map_err_context)?; - Ok::<_, IoError>(items) - }) - } -} - -impl NodeDb { - pub(crate) async fn create_if_not_exists( - node: &NodeDb, - pool: &Pool, - ) -> IoResult { - match NodeDb::find_by_pk(&node.name, pool).await? { - Err(_) => NodeDb::create(node.clone(), pool).await?, - Ok(node) => Ok(node), - } - } + /// The created at date + pub created_at: chrono::NaiveDateTime, } diff --git a/bin/nanocld/src/repositories/mod.rs b/bin/nanocld/src/repositories/mod.rs index 77cb69454..144000307 100644 --- a/bin/nanocld/src/repositories/mod.rs +++ b/bin/nanocld/src/repositories/mod.rs @@ -1,3 +1,4 @@ +mod node; mod cargo; mod process; mod namespace; diff --git a/bin/nanocld/src/repositories/node.rs b/bin/nanocld/src/repositories/node.rs new file mode 100644 index 000000000..b905293e7 --- /dev/null +++ b/bin/nanocld/src/repositories/node.rs @@ -0,0 +1,48 @@ +use diesel::prelude::*; + +use nanocl_error::io::IoResult; + +use nanocl_stubs::generic::GenericFilter; + +use crate::{ + models::{Pool, NodeDb}, + schema::nodes, +}; + +use super::generic::*; + +impl RepositoryBase for NodeDb {} + +impl RepositoryCreate for NodeDb {} + +impl RepositoryDelByPk for NodeDb {} + +impl RepositoryRead for NodeDb { + type Output = NodeDb; + type Query = nodes::BoxedQuery<'static, diesel::pg::Pg>; + + fn gen_read_query(filter: &GenericFilter, is_multiple: bool) -> Self::Query { + let mut query = nodes::dsl::nodes.into_boxed(); + if is_multiple { + query = query.order(nodes::dsl::created_at.desc()); + let limit = filter.limit.unwrap_or(100); + query = query.limit(limit as i64); + if let Some(offset) = filter.offset { + query = query.offset(offset as i64); + } + } + query + } +} + +impl NodeDb { + pub(crate) async fn create_if_not_exists( + node: &NodeDb, + pool: &Pool, + ) -> IoResult { + match NodeDb::read_by_pk(&node.name, pool).await? { + Err(_) => NodeDb::create_from(node.clone(), pool).await?, + Ok(node) => Ok(node), + } + } +} diff --git a/bin/nanocld/src/schema.rs b/bin/nanocld/src/schema.rs index 1c6afb54f..2ff9b2b7f 100644 --- a/bin/nanocld/src/schema.rs +++ b/bin/nanocld/src/schema.rs @@ -96,6 +96,7 @@ diesel::table! { nodes (name) { name -> Varchar, ip_address -> Varchar, + created_at -> Timestamptz, } } diff --git a/bin/nanocld/src/services/node.rs b/bin/nanocld/src/services/node.rs index db9588cbb..93550fd20 100644 --- a/bin/nanocld/src/services/node.rs +++ b/bin/nanocld/src/services/node.rs @@ -1,19 +1,22 @@ -use std::rc::Rc; -use std::cell::RefCell; -use std::time::Instant; +use std::{rc::Rc, cell::RefCell, time::Instant}; -use nanocl_stubs::generic::GenericFilter; -use ntex::{rt, ws, web}; -use ntex::channel::oneshot; -use ntex::util::ByteString; -use ntex::{Service, fn_service, chain}; -use ntex::service::{map_config, fn_shutdown, fn_factory_with_config}; +use ntex::{ + rt, ws, web, Service, chain, fn_service, + channel::oneshot, + util::ByteString, + service::{map_config, fn_shutdown, fn_factory_with_config}, +}; use futures::future::ready; use nanocl_error::http::HttpResult; -use crate::utils; -use crate::models::{DaemonState, WsConState, NodeDb, Repository}; +use nanocl_stubs::generic::GenericFilter; + +use crate::{ + utils, + repositories::generic::*, + models::{DaemonState, WsConState, NodeDb}, +}; /// List nodes #[cfg_attr(feature = "dev", utoipa::path( @@ -28,7 +31,7 @@ use crate::models::{DaemonState, WsConState, NodeDb, Repository}; pub(crate) async fn list_node( state: web::types::State, ) -> HttpResult { - let items = NodeDb::find(&GenericFilter::default(), &state.pool).await??; + let items = NodeDb::read(&GenericFilter::default(), &state.pool).await??; Ok(web::HttpResponse::Ok().json(&items)) } diff --git a/bin/nanocld/src/utils/node.rs b/bin/nanocld/src/utils/node.rs index f0f17fce8..f25abf868 100644 --- a/bin/nanocld/src/utils/node.rs +++ b/bin/nanocld/src/utils/node.rs @@ -6,6 +6,7 @@ pub async fn register(state: &DaemonState) -> IoResult<()> { let node = NodeDb { name: state.config.hostname.clone(), ip_address: state.config.gateway.clone(), + created_at: chrono::Utc::now().naive_utc(), }; NodeDb::create_if_not_exists(&node, &state.pool).await?; Ok(())