Skip to content

Commit

Permalink
refactor/nanocld: with namespace trait
Browse files Browse the repository at this point in the history
  • Loading branch information
leon3s committed Jan 7, 2024
1 parent ec74cc0 commit 93db414
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 131 deletions.
19 changes: 15 additions & 4 deletions bin/nanocl/src/models/namespace.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use chrono::TimeZone;
use tabled::Tabled;
use clap::{Parser, Subcommand};

Expand Down Expand Up @@ -50,23 +51,33 @@ pub struct NamespaceOpts {
#[tabled(rename_all = "UPPERCASE")]
pub struct NamespaceRow {
/// Name of the namespace
pub(crate) name: String,
pub name: String,
/// Number of cargoes
pub(crate) cargoes: i64,
pub cargoes: usize,
/// Number of instances
pub(crate) instances: i64,
pub instances: usize,
/// Default gateway of the namespace
pub(crate) gateway: String,
pub gateway: String,
#[tabled(rename = "CREATED AT")]
pub created_at: String,
}

/// Convert a NamespaceSummary to a NamespaceRow
impl From<NamespaceSummary> for NamespaceRow {
fn from(item: NamespaceSummary) -> Self {
let binding = chrono::Local::now();
let tz = binding.offset();
// Convert the created_at and updated_at to the current timezone
let created_at = tz
.timestamp_opt(item.created_at.timestamp(), 0)
.unwrap()
.format("%Y-%m-%d %H:%M:%S");
Self {
name: item.name,
cargoes: item.cargoes,
instances: item.instances,
gateway: item.gateway,
created_at: created_at.to_string(),
}
}
}
16 changes: 13 additions & 3 deletions bin/nanocld/specs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4910,10 +4910,15 @@ components:
It is used to group cargoes together
required:
- Name
- CreatedAt
properties:
Name:
type: string
description: Name of the namespace
description: The name as primary key of the namespace
CreatedAt:
type: string
format: date-time
description: When the namespace was created
NamespaceInspect:
type: object
description: |-
Expand Down Expand Up @@ -4956,21 +4961,26 @@ components:
- Cargoes
- Instances
- Gateway
- CreatedAt
properties:
Name:
type: string
description: Name of the namespace
Cargoes:
type: integer
format: int64
description: Number of cargoes
minimum: 0
Instances:
type: integer
format: int64
description: Number of instances
minimum: 0
Gateway:
type: string
description: Gateway of the namespace
CreatedAt:
type: string
format: date-time
description: When the namespace was created
Network:
type: object
properties:
Expand Down
15 changes: 12 additions & 3 deletions bin/nanocld/src/models/namespace.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use diesel::prelude::*;
use serde::{Serialize, Deserialize};

use nanocl_stubs::namespace::NamespacePartial;
use nanocl_stubs::namespace::{NamespacePartial, Namespace};

use crate::schema::namespaces;

Expand All @@ -15,9 +15,9 @@ use crate::schema::namespaces;
#[diesel(table_name = namespaces)]
#[serde(rename_all = "PascalCase")]
pub struct NamespaceDb {
/// The name of the namespace
/// The name as primary key of the namespace
pub name: String,
/// The created at date
/// When the namespace was created
pub created_at: chrono::NaiveDateTime,
}

Expand All @@ -39,3 +39,12 @@ impl From<&NamespacePartial> for NamespaceDb {
}
}
}

impl From<NamespaceDb> for Namespace {
fn from(namespace: NamespaceDb) -> Self {
Self {
name: namespace.name,
created_at: namespace.created_at,
}
}
}
1 change: 1 addition & 0 deletions bin/nanocld/src/objects/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ mod cargo;
mod vm;
mod secret;
mod resource;
mod namespace;

pub mod generic;
95 changes: 95 additions & 0 deletions bin/nanocld/src/objects/namespace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use bollard_next::network::{InspectNetworkOptions, CreateNetworkOptions};

use nanocl_error::http::{HttpResult, HttpError};
use nanocl_stubs::namespace::{NamespacePartial, Namespace, NamespaceInspect};

use crate::{
repositories::generic::*,
models::{NamespaceDb, SystemState, CargoDb},
};

use super::generic::*;

impl ObjCreate for NamespaceDb {
type ObjCreateIn = NamespacePartial;
type ObjCreateOut = Namespace;

async fn fn_create_obj(
obj: &Self::ObjCreateIn,
state: &SystemState,
) -> HttpResult<Self::ObjCreateOut> {
if NamespaceDb::read_by_pk(&obj.name, &state.pool)
.await
.is_ok()
{
return Err(HttpError::conflict(format!(
"Namespace {}: already exist",
&obj.name
)));

Check warning on line 28 in bin/nanocld/src/objects/namespace.rs

View check run for this annotation

Codecov / codecov/patch

bin/nanocld/src/objects/namespace.rs#L25-L28

Added lines #L25 - L28 were not covered by tests
}
if state
.docker_api
.inspect_network(&obj.name, None::<InspectNetworkOptions<String>>)
.await
.is_ok()
{
let item = NamespaceDb::create_from(obj, &state.pool).await?;
return Ok(item.into());

Check warning on line 37 in bin/nanocld/src/objects/namespace.rs

View check run for this annotation

Codecov / codecov/patch

bin/nanocld/src/objects/namespace.rs#L36-L37

Added lines #L36 - L37 were not covered by tests
}
let config = CreateNetworkOptions {
name: obj.name.to_owned(),
driver: String::from("bridge"),
..Default::default()
};
state.docker_api.create_network(config).await?;
let item = NamespaceDb::create_from(obj, &state.pool).await?.into();
Ok(item)
}
}

impl ObjInspectByPk for NamespaceDb {
type ObjInspectOut = NamespaceInspect;

async fn inspect_obj_by_pk(
pk: &str,
state: &SystemState,
) -> HttpResult<Self::ObjInspectOut> {
let namespace = NamespaceDb::read_by_pk(pk, &state.pool).await?;
let models =
CargoDb::read_by_namespace(&namespace.name, &state.pool).await?;
let mut cargoes = Vec::new();
for cargo in models {
let cargo =
CargoDb::inspect_obj_by_pk(&cargo.spec.cargo_key, state).await?;
cargoes.push(cargo);

Check warning on line 64 in bin/nanocld/src/objects/namespace.rs

View check run for this annotation

Codecov / codecov/patch

bin/nanocld/src/objects/namespace.rs#L62-L64

Added lines #L62 - L64 were not covered by tests
}
let network = state
.docker_api
.inspect_network(pk, None::<InspectNetworkOptions<String>>)
.await?;
Ok(NamespaceInspect {
name: namespace.name,
cargoes,
network,
})
}
}

impl ObjDelByPk for NamespaceDb {
type ObjDelOpts = ();
type ObjDelOut = Namespace;

async fn fn_del_obj_by_pk(
pk: &str,
_opts: &Self::ObjDelOpts,
state: &SystemState,
) -> HttpResult<Self::ObjDelOut> {
let item = NamespaceDb::read_by_pk(pk, &state.pool).await?;
CargoDb::delete_by_namespace(pk, state).await?;
NamespaceDb::del_by_pk(pk, &state.pool).await?;
if let Err(err) = state.docker_api.remove_network(pk).await {
log::error!("Unable to remove network {} got error: {}", pk, err);

Check warning on line 91 in bin/nanocld/src/objects/namespace.rs

View check run for this annotation

Codecov / codecov/patch

bin/nanocld/src/objects/namespace.rs#L91

Added line #L91 was not covered by tests
}
Ok(item.into())
}
}
12 changes: 5 additions & 7 deletions bin/nanocld/src/services/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use nanocl_stubs::{

use crate::{
utils,
objects::generic::*,
models::{SystemState, NamespaceDb},
repositories::generic::RepositoryReadBy,
};

/// List namespaces
Expand All @@ -32,8 +32,7 @@ pub async fn list_namespace(
) -> HttpResult<web::HttpResponse> {
let filter = GenericFilter::try_from(query.into_inner())
.map_err(|err| HttpError::bad_request(err.to_string()))?;
let items =
utils::namespace::list(&filter, &state.docker_api, &state.pool).await?;
let items = utils::namespace::list(&filter, &state).await?;
Ok(web::HttpResponse::Ok().json(&items))
}

Expand All @@ -55,7 +54,7 @@ pub async fn inspect_namespace(
state: web::types::State<SystemState>,
path: web::types::Path<(String, String)>,
) -> HttpResult<web::HttpResponse> {
let namespace = utils::namespace::inspect_by_name(&path.1, &state).await?;
let namespace = NamespaceDb::inspect_obj_by_pk(&path.1, &state).await?;
Ok(web::HttpResponse::Ok().json(&namespace))
}

Expand All @@ -75,7 +74,7 @@ pub async fn create_namespace(
state: web::types::State<SystemState>,
payload: web::types::Json<NamespacePartial>,
) -> HttpResult<web::HttpResponse> {
let item = utils::namespace::create(&payload, &state).await?;
let item = NamespaceDb::create_obj(&payload, &state).await?;
Ok(web::HttpResponse::Created().json(&item))
}

Expand All @@ -97,8 +96,7 @@ pub async fn delete_namespace(
state: web::types::State<SystemState>,
path: web::types::Path<(String, String)>,
) -> HttpResult<web::HttpResponse> {
NamespaceDb::read_by_pk(&path.1, &state.pool).await?;
utils::namespace::delete_by_name(&path.1, &state).await?;
NamespaceDb::del_obj_by_pk(&path.1, &(), &state).await?;
Ok(web::HttpResponse::Accepted().into())
}

Expand Down
Loading

0 comments on commit 93db414

Please sign in to comment.