mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-12 08:01:04 +00:00
fmt. copy deployment / build
This commit is contained in:
+8
-4
@@ -5,11 +5,12 @@ use monitor_types::{
|
||||
busy::Busy,
|
||||
entities::{
|
||||
build::Build,
|
||||
builder::Builder,
|
||||
deployment::{Deployment, DockerContainerState},
|
||||
server::{Server, ServerStatus},
|
||||
update::Update,
|
||||
user::User,
|
||||
PermissionLevel, builder::Builder,
|
||||
PermissionLevel,
|
||||
},
|
||||
permissioned::Permissioned,
|
||||
};
|
||||
@@ -114,7 +115,10 @@ impl State {
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn get_deployment_state(&self, deployment: &Deployment) -> anyhow::Result<DockerContainerState> {
|
||||
pub async fn get_deployment_state(
|
||||
&self,
|
||||
deployment: &Deployment,
|
||||
) -> anyhow::Result<DockerContainerState> {
|
||||
if deployment.config.server_id.is_empty() {
|
||||
return Ok(DockerContainerState::NotDeployed);
|
||||
}
|
||||
@@ -133,7 +137,7 @@ impl State {
|
||||
|
||||
let state = match container {
|
||||
Some(container) => container.state,
|
||||
None => DockerContainerState::NotDeployed
|
||||
None => DockerContainerState::NotDeployed,
|
||||
};
|
||||
|
||||
Ok(state)
|
||||
@@ -358,4 +362,4 @@ pub fn empty_or_only_spaces(word: &str) -> bool {
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use monitor_types::entities::{
|
||||
deployment::{BasicContainerInfo, Deployment, DockerContainerState},
|
||||
server::{
|
||||
stats::{
|
||||
AllSystemStats, BasicSystemStats, CpuUsage, ServerHealth, SingleDiskUsage, StatsState,
|
||||
AllSystemStats, BasicSystemStats, ServerHealth, SingleDiskUsage, StatsState,
|
||||
SystemComponent,
|
||||
},
|
||||
Server, ServerConfig, ServerStatus,
|
||||
|
||||
@@ -14,9 +14,7 @@ use monitor_types::{
|
||||
},
|
||||
monitor_timestamp,
|
||||
permissioned::Permissioned,
|
||||
requests::api::{
|
||||
CreateBuild, DeleteBuild, Deploy, GetBuild, ListBuilds, RunBuild, UpdateBuild,
|
||||
},
|
||||
requests::api::*,
|
||||
};
|
||||
use mungos::mongodb::bson::{doc, to_bson};
|
||||
use periphery_client::{
|
||||
@@ -112,7 +110,84 @@ impl Resolve<CreateBuild, RequestUser> for State {
|
||||
let build_id = self
|
||||
.db
|
||||
.builds
|
||||
.create_one(&build)
|
||||
.create_one(build)
|
||||
.await
|
||||
.context("failed to add build to db")?;
|
||||
let build = self.get_build(&build_id).await?;
|
||||
let update = Update {
|
||||
target: UpdateTarget::Build(build_id),
|
||||
operation: Operation::CreateBuild,
|
||||
start_ts,
|
||||
end_ts: Some(monitor_timestamp()),
|
||||
operator: user.id.clone(),
|
||||
success: true,
|
||||
logs: vec![
|
||||
Log::simple(
|
||||
"create build",
|
||||
format!("created build\nid: {}\nname: {}", build.id, build.name),
|
||||
),
|
||||
Log::simple("config", format!("{:#?}", build.config)),
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
self.add_update(update).await?;
|
||||
|
||||
Ok(build)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Resolve<CopyBuild, RequestUser> for State {
|
||||
async fn resolve(
|
||||
&self,
|
||||
CopyBuild { name, id }: CopyBuild,
|
||||
user: RequestUser,
|
||||
) -> anyhow::Result<Build> {
|
||||
let Build {
|
||||
config,
|
||||
description,
|
||||
..
|
||||
} = self
|
||||
.get_build_check_permissions(&id, &user, PermissionLevel::Update)
|
||||
.await?;
|
||||
match &config.builder {
|
||||
BuildBuilderConfig::Server { server_id } => {
|
||||
self.get_server_check_permissions(
|
||||
server_id,
|
||||
&user,
|
||||
PermissionLevel::Update,
|
||||
)
|
||||
.await
|
||||
.context("cannot create build on this server. user must have update permissions on the server.")?;
|
||||
}
|
||||
BuildBuilderConfig::Builder { builder_id } => {
|
||||
self.get_builder_check_permissions(
|
||||
builder_id,
|
||||
&user,
|
||||
PermissionLevel::Read,
|
||||
)
|
||||
.await
|
||||
.context("cannot create build using this builder. user must have at least read permissions on the builder.")?;
|
||||
}
|
||||
}
|
||||
let start_ts = monitor_timestamp();
|
||||
let build = Build {
|
||||
id: Default::default(),
|
||||
name,
|
||||
created_at: start_ts,
|
||||
updated_at: start_ts,
|
||||
last_built_at: 0,
|
||||
permissions: [(user.id.clone(), PermissionLevel::Update)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
description,
|
||||
config,
|
||||
};
|
||||
let build_id = self
|
||||
.db
|
||||
.builds
|
||||
.create_one(build)
|
||||
.await
|
||||
.context("failed to add build to db")?;
|
||||
let build = self.get_build(&build_id).await?;
|
||||
|
||||
@@ -10,10 +10,7 @@ use monitor_types::{
|
||||
},
|
||||
get_image_name, monitor_timestamp,
|
||||
permissioned::Permissioned,
|
||||
requests::api::{
|
||||
CreateDeployment, DeleteDeployment, Deploy, GetDeployment, ListDeployments,
|
||||
RemoveContainer, RenameDeployment, StartContainer, StopContainer, UpdateDeployment,
|
||||
},
|
||||
requests::api::*,
|
||||
to_monitor_name,
|
||||
};
|
||||
use mungos::mongodb::bson::{doc, to_bson};
|
||||
@@ -71,14 +68,18 @@ impl Resolve<CreateDeployment, RequestUser> for State {
|
||||
user: RequestUser,
|
||||
) -> anyhow::Result<Deployment> {
|
||||
if let Some(server_id) = &config.server_id {
|
||||
self.get_server_check_permissions(server_id, &user, PermissionLevel::Update)
|
||||
.await
|
||||
.context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?;
|
||||
if !server_id.is_empty() {
|
||||
self.get_server_check_permissions(server_id, &user, PermissionLevel::Update)
|
||||
.await
|
||||
.context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?;
|
||||
}
|
||||
}
|
||||
if let Some(DeploymentImage::Build { build_id, .. }) = &config.image {
|
||||
self.get_build_check_permissions(build_id, &user, PermissionLevel::Read)
|
||||
.await
|
||||
.context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?;
|
||||
if !build_id.is_empty() {
|
||||
self.get_build_check_permissions(build_id, &user, PermissionLevel::Read)
|
||||
.await
|
||||
.context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?;
|
||||
}
|
||||
}
|
||||
let start_ts = monitor_timestamp();
|
||||
let deployment = Deployment {
|
||||
@@ -125,6 +126,77 @@ impl Resolve<CreateDeployment, RequestUser> for State {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Resolve<CopyDeployment, RequestUser> for State {
|
||||
async fn resolve(
|
||||
&self,
|
||||
CopyDeployment { name, id }: CopyDeployment,
|
||||
user: RequestUser,
|
||||
) -> anyhow::Result<Deployment> {
|
||||
let Deployment {
|
||||
config,
|
||||
description,
|
||||
..
|
||||
} = self
|
||||
.get_deployment_check_permissions(&id, &user, PermissionLevel::Update)
|
||||
.await?;
|
||||
if !config.server_id.is_empty() {
|
||||
self.get_server_check_permissions(&config.server_id, &user, PermissionLevel::Update)
|
||||
.await
|
||||
.context("cannot create deployment on this server. user must have update permissions on the server to perform this action.")?;
|
||||
}
|
||||
if let DeploymentImage::Build { build_id, .. } = &config.image {
|
||||
if !build_id.is_empty() {
|
||||
self.get_build_check_permissions(build_id, &user, PermissionLevel::Read)
|
||||
.await
|
||||
.context("cannot create deployment with this build attached. user must have at least read permissions on the build to perform this action.")?;
|
||||
}
|
||||
}
|
||||
let start_ts = monitor_timestamp();
|
||||
let deployment = Deployment {
|
||||
id: Default::default(),
|
||||
name,
|
||||
created_at: start_ts,
|
||||
updated_at: start_ts,
|
||||
permissions: [(user.id.clone(), PermissionLevel::Update)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
description,
|
||||
config,
|
||||
};
|
||||
let deployment_id = self
|
||||
.db
|
||||
.deployments
|
||||
.create_one(&deployment)
|
||||
.await
|
||||
.context("failed to add deployment to db")?;
|
||||
let deployment = self.get_deployment(&deployment_id).await?;
|
||||
let update = Update {
|
||||
target: UpdateTarget::Deployment(deployment_id),
|
||||
operation: Operation::CreateDeployment,
|
||||
start_ts,
|
||||
end_ts: Some(monitor_timestamp()),
|
||||
operator: user.id.clone(),
|
||||
success: true,
|
||||
logs: vec![
|
||||
Log::simple(
|
||||
"create deployment",
|
||||
format!(
|
||||
"created deployment\nid: {}\nname: {}",
|
||||
deployment.id, deployment.name
|
||||
),
|
||||
),
|
||||
Log::simple("config", format!("{:#?}", deployment.config)),
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
self.add_update(update).await?;
|
||||
|
||||
Ok(deployment)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Resolve<DeleteDeployment, RequestUser> for State {
|
||||
async fn resolve(
|
||||
|
||||
@@ -15,10 +15,10 @@ use crate::{
|
||||
state::{State, StateExtension},
|
||||
};
|
||||
|
||||
mod build;
|
||||
mod deployment;
|
||||
mod secret;
|
||||
mod server;
|
||||
mod build;
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolver)]
|
||||
@@ -70,7 +70,7 @@ pub enum ApiRequest {
|
||||
// ==== DEPLOYMENT ====
|
||||
//
|
||||
GetDeployment(GetDeployment),
|
||||
ListDeployments(ListDeployments),
|
||||
ListDeployments(ListDeployments),
|
||||
// CRUD
|
||||
CreateDeployment(CreateDeployment),
|
||||
DeleteDeployment(DeleteDeployment),
|
||||
@@ -86,7 +86,7 @@ pub enum ApiRequest {
|
||||
// ==== BUILD ====
|
||||
//
|
||||
GetBuild(GetBuild),
|
||||
ListBuilds(ListBuilds),
|
||||
ListBuilds(ListBuilds),
|
||||
// CRUD
|
||||
CreateBuild(CreateBuild),
|
||||
DeleteBuild(DeleteBuild),
|
||||
@@ -105,18 +105,26 @@ pub fn router() -> Router {
|
||||
Json(request): Json<ApiRequest>| async move {
|
||||
let timer = Instant::now();
|
||||
let req_id = Uuid::new_v4();
|
||||
info!("/auth request {req_id} | {request:?}");
|
||||
let res = state
|
||||
.resolve_request(request, user)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")));
|
||||
info!("/api request {req_id} | {request:?}");
|
||||
let res = tokio::spawn(async move {
|
||||
state
|
||||
.resolve_request(request, user)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")))
|
||||
})
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")));
|
||||
if let Err(e) = &res {
|
||||
info!("/auth request {req_id} ERROR: {e:?}");
|
||||
info!("/api request {req_id} SPAWN ERROR: {e:?}");
|
||||
}
|
||||
let res = res?;
|
||||
if let Err(e) = &res {
|
||||
info!("/api request {req_id} ERROR: {e:?}");
|
||||
}
|
||||
let res = res?;
|
||||
let elapsed = timer.elapsed();
|
||||
info!("/auth request {req_id} | resolve time: {elapsed:?}");
|
||||
debug!("/auth request {req_id} RESPONSE: {res}");
|
||||
info!("/api request {req_id} | resolve time: {elapsed:?}");
|
||||
debug!("/api request {req_id} RESPONSE: {res}");
|
||||
Result::<_, (StatusCode, String)>::Ok((TypedHeader(ContentType::json()), res))
|
||||
},
|
||||
),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use anyhow::{anyhow, Context};
|
||||
use async_trait::async_trait;
|
||||
use monitor_types::{
|
||||
monitor_timestamp,
|
||||
entities::user::ApiSecret,
|
||||
monitor_timestamp,
|
||||
requests::api::{CreateLoginSecret, CreateLoginSecretResponse, DeleteLoginSecret},
|
||||
};
|
||||
use mungos::{
|
||||
|
||||
@@ -12,13 +12,7 @@ use monitor_types::{
|
||||
},
|
||||
monitor_timestamp,
|
||||
permissioned::Permissioned,
|
||||
requests::api::{
|
||||
CreateServer, DeleteServer, GetAllSystemStats, GetBasicSystemStats, GetCpuUsage,
|
||||
GetDiskUsage, GetDockerContainers, GetDockerImages, GetDockerNetworks, GetNetworkUsage,
|
||||
GetPeripheryVersion, GetPeripheryVersionResponse, GetServer, GetSystemComponents,
|
||||
GetSystemInformation, GetSystemProcesses, ListServers, PruneDockerContainers,
|
||||
PruneDockerImages, PruneDockerNetworks, RenameServer, UpdateServer,
|
||||
},
|
||||
requests::api::*,
|
||||
};
|
||||
use mungos::mongodb::bson::{doc, to_bson};
|
||||
use periphery_client::requests;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use crate::entities::{server::ServerActionState, deployment::DeploymentActionState, build::BuildActionState};
|
||||
use crate::entities::{
|
||||
build::BuildActionState, deployment::DeploymentActionState, server::ServerActionState,
|
||||
};
|
||||
|
||||
pub trait Busy {
|
||||
fn busy(&self) -> bool;
|
||||
@@ -27,4 +29,4 @@ impl Busy for BuildActionState {
|
||||
fn busy(&self) -> bool {
|
||||
self.building || self.updating
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use partial_derive2::Partial;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::{I64, i64_is_zero};
|
||||
use crate::{i64_is_zero, I64};
|
||||
|
||||
use super::PermissionsMap;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use mungos::MungosIndexed;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::{I64, i64_is_zero};
|
||||
use crate::{i64_is_zero, I64};
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, MungosIndexed)]
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use crate::entities::{PermissionsMap, PermissionLevel, deployment::Deployment, build::Build, server::Server, builder::Builder};
|
||||
use crate::entities::{
|
||||
build::Build, builder::Builder, deployment::Deployment, server::Server, PermissionLevel,
|
||||
PermissionsMap,
|
||||
};
|
||||
|
||||
pub trait Permissioned {
|
||||
fn permissions_map(&self) -> &PermissionsMap;
|
||||
@@ -30,4 +33,4 @@ impl Permissioned for Builder {
|
||||
fn permissions_map(&self) -> &PermissionsMap {
|
||||
&self.permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,16 @@ pub struct CreateBuild {
|
||||
|
||||
//
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
|
||||
#[response(Build)]
|
||||
pub struct CopyBuild {
|
||||
pub name: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
|
||||
#[response(Build)]
|
||||
|
||||
@@ -8,6 +8,4 @@
|
||||
// MongoDocument,
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// derive_crud_requests!(Builder);
|
||||
// derive_crud_requests!(Builder);
|
||||
|
||||
@@ -40,6 +40,16 @@ pub struct CreateDeployment {
|
||||
|
||||
//
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
|
||||
#[response(Deployment)]
|
||||
pub struct CopyDeployment {
|
||||
pub name: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
|
||||
#[response(Deployment)]
|
||||
|
||||
+12
-4
@@ -36,10 +36,18 @@ async fn app() -> anyhow::Result<()> {
|
||||
let timer = Instant::now();
|
||||
let req_id = Uuid::new_v4();
|
||||
info!("request {req_id} | {request:?}");
|
||||
let res = state
|
||||
.resolve_request(request, ())
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")));
|
||||
let res = tokio::spawn(async move {
|
||||
state
|
||||
.resolve_request(request, ())
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")))
|
||||
})
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")));
|
||||
if let Err(e) = &res {
|
||||
debug!("request {req_id} SPAWN ERROR: {e:?}");
|
||||
}
|
||||
let res = res?;
|
||||
if let Err(e) = &res {
|
||||
debug!("request {req_id} ERROR: {e:?}");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use async_trait::async_trait;
|
||||
use monitor_types::{entities::{server::docker_image::ImageSummary, update::Log}, optional_string};
|
||||
use monitor_types::{
|
||||
entities::{server::docker_image::ImageSummary, update::Log},
|
||||
optional_string,
|
||||
};
|
||||
use resolver_api::{derive::Request, Resolve};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use monitor_types::{entities::{update::Log, CloneArgs, SystemCommand}, to_monitor_name};
|
||||
use monitor_types::{
|
||||
entities::{update::Log, CloneArgs, SystemCommand},
|
||||
to_monitor_name,
|
||||
};
|
||||
use resolver_api::{derive::Request, Resolve};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user