diff --git a/bin/core/src/api/execute/repo.rs b/bin/core/src/api/execute/repo.rs index 03e150612..d74e184c3 100644 --- a/bin/core/src/api/execute/repo.rs +++ b/bin/core/src/api/execute/repo.rs @@ -3,7 +3,7 @@ use std::{collections::HashSet, future::IntoFuture, time::Duration}; use anyhow::{anyhow, Context}; use formatting::format_serror; use komodo_client::{ - api::execute::*, + api::{execute::*, write::RefreshRepoCache}, entities::{ alert::{Alert, AlertData, SeverityLevel}, builder::{Builder, BuilderConfig}, @@ -123,6 +123,17 @@ impl Resolve for State { update_last_pulled_time(&repo.name).await; } + if let Err(e) = State + .resolve(RefreshRepoCache { repo: repo.id }, user) + .await + .context("Failed to refresh repo cache") + { + update.push_error_log( + "Refresh Repo cache", + format_serror(&e.into()), + ); + }; + handle_server_update_return(update).await } } @@ -207,6 +218,17 @@ impl Resolve for State { update_last_pulled_time(&repo.name).await; } + if let Err(e) = State + .resolve(RefreshRepoCache { repo: repo.id }, user) + .await + .context("Failed to refresh repo cache") + { + update.push_error_log( + "Refresh Repo cache", + format_serror(&e.into()), + ); + }; + handle_server_update_return(update).await } } diff --git a/bin/core/src/api/write/action.rs b/bin/core/src/api/write/action.rs index 1924580d7..f18c3a6b9 100644 --- a/bin/core/src/api/write/action.rs +++ b/bin/core/src/api/write/action.rs @@ -1,7 +1,8 @@ use komodo_client::{ api::write::*, entities::{ - action::Action, permission::PermissionLevel, user::User, + action::Action, permission::PermissionLevel, update::Update, + user::User, }, }; use resolver_api::Resolve; @@ -47,6 +48,17 @@ impl Resolve for State { } } +impl Resolve for State { + #[instrument(name = "RenameAction", skip(self, user))] + async fn resolve( + &self, + RenameAction { id, name }: RenameAction, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} + impl Resolve for State { #[instrument(name = "DeleteAction", skip(self, user))] async fn resolve( diff --git a/bin/core/src/api/write/alerter.rs b/bin/core/src/api/write/alerter.rs index 0182170d2..2047f4872 100644 --- a/bin/core/src/api/write/alerter.rs +++ b/bin/core/src/api/write/alerter.rs @@ -1,9 +1,8 @@ use komodo_client::{ - api::write::{ - CopyAlerter, CreateAlerter, DeleteAlerter, UpdateAlerter, - }, + api::write::*, entities::{ - alerter::Alerter, permission::PermissionLevel, user::User, + alerter::Alerter, permission::PermissionLevel, update::Update, + user::User, }, }; use resolver_api::Resolve; @@ -59,3 +58,14 @@ impl Resolve for State { resource::update::(&id, config, &user).await } } + +impl Resolve for State { + #[instrument(name = "RenameAlerter", skip(self, user))] + async fn resolve( + &self, + RenameAlerter { id, name }: RenameAlerter, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} diff --git a/bin/core/src/api/write/build.rs b/bin/core/src/api/write/build.rs index 72a83857c..e1ee86abd 100644 --- a/bin/core/src/api/write/build.rs +++ b/bin/core/src/api/write/build.rs @@ -6,6 +6,7 @@ use komodo_client::{ build::{Build, BuildInfo, PartialBuildConfig}, config::core::CoreConfig, permission::PermissionLevel, + update::Update, user::User, CloneArgs, NoData, }, @@ -77,6 +78,17 @@ impl Resolve for State { } } +impl Resolve for State { + #[instrument(name = "RenameBuild", skip(self, user))] + async fn resolve( + &self, + RenameBuild { id, name }: RenameBuild, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} + impl Resolve for State { #[instrument( name = "RefreshBuildCache", diff --git a/bin/core/src/api/write/builder.rs b/bin/core/src/api/write/builder.rs index 31b469d8a..d99fabe0d 100644 --- a/bin/core/src/api/write/builder.rs +++ b/bin/core/src/api/write/builder.rs @@ -1,7 +1,8 @@ use komodo_client::{ api::write::*, entities::{ - builder::Builder, permission::PermissionLevel, user::User, + builder::Builder, permission::PermissionLevel, update::Update, + user::User, }, }; use resolver_api::Resolve; @@ -57,3 +58,14 @@ impl Resolve for State { resource::update::(&id, config, &user).await } } + +impl Resolve for State { + #[instrument(name = "RenameBuilder", skip(self, user))] + async fn resolve( + &self, + RenameBuilder { id, name }: RenameBuilder, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} diff --git a/bin/core/src/api/write/deployment.rs b/bin/core/src/api/write/deployment.rs index a6e94ba1b..309fe69a4 100644 --- a/bin/core/src/api/write/deployment.rs +++ b/bin/core/src/api/write/deployment.rs @@ -108,7 +108,7 @@ impl Resolve for State { if container_state == DeploymentState::Unknown { return Err(anyhow!( - "cannot rename deployment when container status is unknown" + "Cannot rename Deployment when container status is unknown" )); } @@ -124,7 +124,7 @@ impl Resolve for State { None, ) .await - .context("failed to update deployment name on db")?; + .context("Failed to update Deployment name on db")?; if container_state != DeploymentState::NotDeployed { let server = @@ -135,20 +135,19 @@ impl Resolve for State { new_name: name.clone(), }) .await - .context("failed to rename container on server")?; + .context("Failed to rename container on server")?; update.logs.push(log); } update.push_simple_log( - "rename deployment", + "Rename Deployment", format!( - "renamed deployment from {} to {}", + "Renamed Deployment from {} to {}", deployment.name, name ), ); update.finalize(); - - add_update(update.clone()).await?; + update.id = add_update(update.clone()).await?; Ok(update) } diff --git a/bin/core/src/api/write/mod.rs b/bin/core/src/api/write/mod.rs index 835cf55d6..400bfa75f 100644 --- a/bin/core/src/api/write/mod.rs +++ b/bin/core/src/api/write/mod.rs @@ -89,6 +89,7 @@ pub enum WriteRequest { CopyBuild(CopyBuild), DeleteBuild(DeleteBuild), UpdateBuild(UpdateBuild), + RenameBuild(RenameBuild), RefreshBuildCache(RefreshBuildCache), CreateBuildWebhook(CreateBuildWebhook), DeleteBuildWebhook(DeleteBuildWebhook), @@ -98,18 +99,21 @@ pub enum WriteRequest { CopyBuilder(CopyBuilder), DeleteBuilder(DeleteBuilder), UpdateBuilder(UpdateBuilder), + RenameBuilder(RenameBuilder), // ==== SERVER TEMPLATE ==== CreateServerTemplate(CreateServerTemplate), CopyServerTemplate(CopyServerTemplate), DeleteServerTemplate(DeleteServerTemplate), UpdateServerTemplate(UpdateServerTemplate), + RenameServerTemplate(RenameServerTemplate), // ==== REPO ==== CreateRepo(CreateRepo), CopyRepo(CopyRepo), DeleteRepo(DeleteRepo), UpdateRepo(UpdateRepo), + RenameRepo(RenameRepo), RefreshRepoCache(RefreshRepoCache), CreateRepoWebhook(CreateRepoWebhook), DeleteRepoWebhook(DeleteRepoWebhook), @@ -119,24 +123,28 @@ pub enum WriteRequest { CopyAlerter(CopyAlerter), DeleteAlerter(DeleteAlerter), UpdateAlerter(UpdateAlerter), + RenameAlerter(RenameAlerter), // ==== PROCEDURE ==== CreateProcedure(CreateProcedure), CopyProcedure(CopyProcedure), DeleteProcedure(DeleteProcedure), UpdateProcedure(UpdateProcedure), + RenameProcedure(RenameProcedure), // ==== ACTION ==== CreateAction(CreateAction), CopyAction(CopyAction), DeleteAction(DeleteAction), UpdateAction(UpdateAction), + RenameAction(RenameAction), // ==== SYNC ==== CreateResourceSync(CreateResourceSync), CopyResourceSync(CopyResourceSync), DeleteResourceSync(DeleteResourceSync), UpdateResourceSync(UpdateResourceSync), + RenameResourceSync(RenameResourceSync), WriteSyncFileContents(WriteSyncFileContents), CommitSync(CommitSync), RefreshResourceSyncPending(RefreshResourceSyncPending), diff --git a/bin/core/src/api/write/procedure.rs b/bin/core/src/api/write/procedure.rs index d0549dd45..393c6d820 100644 --- a/bin/core/src/api/write/procedure.rs +++ b/bin/core/src/api/write/procedure.rs @@ -1,7 +1,8 @@ use komodo_client::{ api::write::*, entities::{ - permission::PermissionLevel, procedure::Procedure, user::User, + permission::PermissionLevel, procedure::Procedure, + update::Update, user::User, }, }; use resolver_api::Resolve; @@ -48,6 +49,17 @@ impl Resolve for State { } } +impl Resolve for State { + #[instrument(name = "RenameProcedure", skip(self, user))] + async fn resolve( + &self, + RenameProcedure { id, name }: RenameProcedure, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} + impl Resolve for State { #[instrument(name = "DeleteProcedure", skip(self, user))] async fn resolve( diff --git a/bin/core/src/api/write/repo.rs b/bin/core/src/api/write/repo.rs index 33d2790ab..01185c768 100644 --- a/bin/core/src/api/write/repo.rs +++ b/bin/core/src/api/write/repo.rs @@ -1,27 +1,36 @@ use anyhow::{anyhow, Context}; +use formatting::format_serror; use git::GitRes; use komodo_client::{ api::write::*, entities::{ config::core::CoreConfig, + komodo_timestamp, permission::PermissionLevel, repo::{PartialRepoConfig, Repo, RepoInfo}, + server::Server, + to_komodo_name, + update::{Log, Update}, user::User, - CloneArgs, NoData, + CloneArgs, NoData, Operation, }, }; use mongo_indexed::doc; -use mungos::mongodb::bson::to_document; +use mungos::{by_id::update_one_by_id, mongodb::bson::to_document}; use octorust::types::{ ReposCreateWebhookRequest, ReposCreateWebhookRequestConfig, }; +use periphery_client::api; use resolver_api::Resolve; use crate::{ config::core_config, - helpers::git_token, + helpers::{ + git_token, periphery_client, + update::{add_update, make_update}, + }, resource, - state::{db_client, github_client, State}, + state::{action_states, db_client, github_client, State}, }; impl Resolve for State { @@ -75,6 +84,81 @@ impl Resolve for State { } } +impl Resolve for State { + #[instrument(name = "RenameRepo", skip(self, user))] + async fn resolve( + &self, + RenameRepo { id, name }: RenameRepo, + user: User, + ) -> anyhow::Result { + let repo = resource::get_check_permissions::( + &id, + &user, + PermissionLevel::Write, + ) + .await?; + + if repo.config.server_id.is_empty() + || !repo.config.path.is_empty() + { + return resource::rename::(&repo.id, &name, &user).await; + } + + // get the action state for the repo (or insert default). + let action_state = + action_states().repo.get_or_insert_default(&repo.id).await; + + // Will check to ensure repo not already busy before updating, and return Err if so. + // The returned guard will set the action state back to default when dropped. + let _action_guard = + action_state.update(|state| state.renaming = true)?; + + let name = to_komodo_name(&name); + + let mut update = make_update(&repo, Operation::RenameRepo, &user); + + update_one_by_id( + &db_client().repos, + &repo.id, + mungos::update::Update::Set( + doc! { "name": &name, "updated_at": komodo_timestamp() }, + ), + None, + ) + .await + .context("Failed to update Repo name on db")?; + + let server = + resource::get::(&repo.config.server_id).await?; + + let log = match periphery_client(&server)? + .request(api::git::RenameRepo { + curr_name: to_komodo_name(&repo.name), + new_name: name.clone(), + }) + .await + .context("Failed to rename Repo directory on Server") + { + Ok(log) => log, + Err(e) => Log::error( + "Rename Repo directory failure", + format_serror(&e.into()), + ), + }; + + update.logs.push(log); + + update.push_simple_log( + "Rename Repo", + format!("Renamed Repo from {} to {}", repo.name, name), + ); + update.finalize(); + update.id = add_update(update.clone()).await?; + + Ok(update) + } +} + impl Resolve for State { #[instrument( name = "RefreshRepoCache", diff --git a/bin/core/src/api/write/server.rs b/bin/core/src/api/write/server.rs index 797833adb..d9a60abc7 100644 --- a/bin/core/src/api/write/server.rs +++ b/bin/core/src/api/write/server.rs @@ -1,9 +1,7 @@ -use anyhow::Context; use formatting::format_serror; use komodo_client::{ api::write::*, entities::{ - komodo_timestamp, permission::PermissionLevel, server::Server, update::{Update, UpdateStatus}, @@ -11,7 +9,6 @@ use komodo_client::{ Operation, }, }; -use mungos::{by_id::update_one_by_id, mongodb::bson::doc}; use periphery_client::api; use resolver_api::Resolve; @@ -21,7 +18,7 @@ use crate::{ update::{add_update, make_update, update_update}, }, resource, - state::{db_client, State}, + state::State, }; impl Resolve for State { @@ -64,25 +61,7 @@ impl Resolve for State { RenameServer { id, name }: RenameServer, user: User, ) -> anyhow::Result { - let server = resource::get_check_permissions::( - &id, - &user, - PermissionLevel::Write, - ) - .await?; - let mut update = - make_update(&server, Operation::RenameServer, &user); - - update_one_by_id(&db_client().servers, &id, mungos::update::Update::Set(doc! { "name": &name, "updated_at": komodo_timestamp() }), None) - .await - .context("failed to update server on db. this name may already be taken.")?; - update.push_simple_log( - "rename server", - format!("renamed server {id} from {} to {name}", server.name), - ); - update.finalize(); - update.id = add_update(update.clone()).await?; - Ok(update) + resource::rename::(&id, &name, &user).await } } diff --git a/bin/core/src/api/write/server_template.rs b/bin/core/src/api/write/server_template.rs index 016470b15..0a873349d 100644 --- a/bin/core/src/api/write/server_template.rs +++ b/bin/core/src/api/write/server_template.rs @@ -1,11 +1,11 @@ use komodo_client::{ api::write::{ CopyServerTemplate, CreateServerTemplate, DeleteServerTemplate, - UpdateServerTemplate, + RenameServerTemplate, UpdateServerTemplate, }, entities::{ permission::PermissionLevel, server_template::ServerTemplate, - user::User, + update::Update, user::User, }, }; use resolver_api::Resolve; @@ -63,3 +63,14 @@ impl Resolve for State { resource::update::(&id, config, &user).await } } + +impl Resolve for State { + #[instrument(name = "RenameServerTemplate", skip(self, user))] + async fn resolve( + &self, + RenameServerTemplate { id, name }: RenameServerTemplate, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} diff --git a/bin/core/src/api/write/stack.rs b/bin/core/src/api/write/stack.rs index 0e67cdeb0..681fe31fe 100644 --- a/bin/core/src/api/write/stack.rs +++ b/bin/core/src/api/write/stack.rs @@ -4,7 +4,6 @@ use komodo_client::{ api::write::*, entities::{ config::core::CoreConfig, - komodo_timestamp, permission::PermissionLevel, server::ServerState, stack::{PartialStackConfig, Stack, StackInfo}, @@ -13,10 +12,7 @@ use komodo_client::{ FileContents, NoData, Operation, }, }; -use mungos::{ - by_id::update_one_by_id, - mongodb::bson::{doc, to_document}, -}; +use mungos::mongodb::bson::{doc, to_document}; use octorust::types::{ ReposCreateWebhookRequest, ReposCreateWebhookRequestConfig, }; @@ -100,36 +96,7 @@ impl Resolve for State { RenameStack { id, name }: RenameStack, user: User, ) -> anyhow::Result { - let stack = resource::get_check_permissions::( - &id, - &user, - PermissionLevel::Write, - ) - .await?; - - let mut update = - make_update(&stack, Operation::RenameStack, &user); - - update_one_by_id( - &db_client().stacks, - &stack.id, - mungos::update::Update::Set( - doc! { "name": &name, "updated_at": komodo_timestamp() }, - ), - None, - ) - .await - .context("failed to update stack name on db")?; - - update.push_simple_log( - "rename stack", - format!("renamed stack from {} to {}", stack.name, name), - ); - update.finalize(); - - add_update(update.clone()).await?; - - Ok(update) + resource::rename::(&id, &name, &user).await } } diff --git a/bin/core/src/api/write/sync.rs b/bin/core/src/api/write/sync.rs index 6c4293ed1..7d522c657 100644 --- a/bin/core/src/api/write/sync.rs +++ b/bin/core/src/api/write/sync.rs @@ -5,9 +5,29 @@ use formatting::format_serror; use komodo_client::{ api::{read::ExportAllResourcesToToml, write::*}, entities::{ - self, action::Action, alert::{Alert, AlertData, SeverityLevel}, alerter::Alerter, all_logs_success, build::Build, builder::Builder, config::core::CoreConfig, deployment::Deployment, komodo_timestamp, permission::PermissionLevel, procedure::Procedure, repo::Repo, server::Server, server_template::ServerTemplate, stack::Stack, sync::{ + self, + action::Action, + alert::{Alert, AlertData, SeverityLevel}, + alerter::Alerter, + all_logs_success, + build::Build, + builder::Builder, + config::core::CoreConfig, + deployment::Deployment, + komodo_timestamp, + permission::PermissionLevel, + procedure::Procedure, + repo::Repo, + server::Server, + server_template::ServerTemplate, + stack::Stack, + sync::{ PartialResourceSyncConfig, ResourceSync, ResourceSyncInfo, - }, to_komodo_name, update::{Log, Update}, user::{sync_user, User}, CloneArgs, NoData, Operation, ResourceTarget + }, + to_komodo_name, + update::{Log, Update}, + user::{sync_user, User}, + CloneArgs, NoData, Operation, ResourceTarget, }, }; use mungos::{ @@ -87,6 +107,17 @@ impl Resolve for State { } } +impl Resolve for State { + #[instrument(name = "RenameResourceSync", skip(self, user))] + async fn resolve( + &self, + RenameResourceSync { id, name }: RenameResourceSync, + user: User, + ) -> anyhow::Result { + resource::rename::(&id, &name, &user).await + } +} + impl Resolve for State { async fn resolve( &self, diff --git a/bin/core/src/resource/action.rs b/bin/core/src/resource/action.rs index 22c0ca202..72688a20a 100644 --- a/bin/core/src/resource/action.rs +++ b/bin/core/src/resource/action.rs @@ -31,8 +31,8 @@ impl super::KomodoResource for Action { ResourceTargetVariant::Action } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().actions } @@ -105,11 +105,16 @@ impl super::KomodoResource for Action { } async fn post_update( - _updated: &Self, - _update: &mut Update, + updated: &Self, + update: &mut Update, ) -> anyhow::Result<()> { - refresh_action_state_cache().await; - Ok(()) + Self::post_create(updated, update).await + } + + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameAction } // DELETE diff --git a/bin/core/src/resource/alerter.rs b/bin/core/src/resource/alerter.rs index ca0f42475..c884eb2be 100644 --- a/bin/core/src/resource/alerter.rs +++ b/bin/core/src/resource/alerter.rs @@ -25,8 +25,8 @@ impl super::KomodoResource for Alerter { ResourceTargetVariant::Alerter } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().alerters } @@ -94,6 +94,12 @@ impl super::KomodoResource for Alerter { Ok(()) } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameAlerter + } + // DELETE fn delete_operation() -> Operation { diff --git a/bin/core/src/resource/build.rs b/bin/core/src/resource/build.rs index 5a8782dc5..d6c39dc14 100644 --- a/bin/core/src/resource/build.rs +++ b/bin/core/src/resource/build.rs @@ -38,8 +38,8 @@ impl super::KomodoResource for Build { ResourceTargetVariant::Build } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().builds } @@ -118,11 +118,16 @@ impl super::KomodoResource for Build { } async fn post_update( - _updated: &Self, - _update: &mut Update, + updated: &Self, + update: &mut Update, ) -> anyhow::Result<()> { - refresh_build_state_cache().await; - Ok(()) + Self::post_create(updated, update).await + } + + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameBuild } // DELETE diff --git a/bin/core/src/resource/builder.rs b/bin/core/src/resource/builder.rs index cd608fab6..b85e9e6bb 100644 --- a/bin/core/src/resource/builder.rs +++ b/bin/core/src/resource/builder.rs @@ -31,8 +31,8 @@ impl super::KomodoResource for Builder { ResourceTargetVariant::Builder } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().builders } @@ -118,6 +118,12 @@ impl super::KomodoResource for Builder { Ok(()) } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameBuilder + } + // DELETE fn delete_operation() -> Operation { diff --git a/bin/core/src/resource/deployment.rs b/bin/core/src/resource/deployment.rs index 68cce062f..233926745 100644 --- a/bin/core/src/resource/deployment.rs +++ b/bin/core/src/resource/deployment.rs @@ -26,7 +26,6 @@ use crate::{ query::get_deployment_state, }, monitor::update_cache_for_server, - resource, state::{action_states, db_client, deployment_status_cache}, }; @@ -44,8 +43,8 @@ impl super::KomodoResource for Deployment { ResourceTargetVariant::Deployment } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().deployments } @@ -132,11 +131,21 @@ impl super::KomodoResource for Deployment { created: &Resource, _update: &mut Update, ) -> anyhow::Result<()> { - if !created.config.server_id.is_empty() { - let server = - resource::get::(&created.config.server_id).await?; - update_cache_for_server(&server).await; + if created.config.server_id.is_empty() { + return Ok(()); } + let Ok(server) = super::get::(&created.config.server_id) + .await + .inspect_err(|e| { + warn!( + "Failed to get Server for Deployment {} | {e:#}", + created.name + ) + }) + else { + return Ok(()); + }; + update_cache_for_server(&server).await; Ok(()) } @@ -156,14 +165,15 @@ impl super::KomodoResource for Deployment { async fn post_update( updated: &Self, - _update: &mut Update, + update: &mut Update, ) -> anyhow::Result<()> { - if !updated.config.server_id.is_empty() { - let server = - resource::get::(&updated.config.server_id).await?; - update_cache_for_server(&server).await; - } - Ok(()) + Self::post_create(updated, update).await + } + + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameDeployment } // DELETE diff --git a/bin/core/src/resource/mod.rs b/bin/core/src/resource/mod.rs index e30b97260..3255dcb3a 100644 --- a/bin/core/src/resource/mod.rs +++ b/bin/core/src/resource/mod.rs @@ -110,8 +110,7 @@ pub trait KomodoResource { fn resource_type() -> ResourceTargetVariant; - async fn coll( - ) -> &'static Collection>; + fn coll() -> &'static Collection>; async fn to_list_item( resource: Resource, @@ -169,6 +168,12 @@ pub trait KomodoResource { update: &mut Update, ) -> anyhow::Result<()>; + // ======= + // RENAME + // ======= + + fn rename_operation() -> Operation; + // ======= // DELETE // ======= @@ -199,7 +204,6 @@ pub async fn get( id_or_name: &str, ) -> anyhow::Result> { T::coll() - .await .find_one(id_or_name_filter(id_or_name)) .await .context("failed to query db for resource")? @@ -289,7 +293,7 @@ pub async fn get_resource_ids_for_user( let (base, perms) = tokio::try_join!( // Get any resources with non-none base permission, find_collect( - T::coll().await, + T::coll(), doc! { "base_permission": { "$exists": true, "$ne": "None" } }, None, ) @@ -440,7 +444,7 @@ pub async fn list_full_for_user_using_document( filters.insert("_id", doc! { "$in": ids }); } find_collect( - T::coll().await, + T::coll(), filters, FindOptions::builder().sort(doc! { "name": 1 }).build(), ) @@ -463,7 +467,7 @@ pub async fn get_id_to_resource_map( id_to_tags: &HashMap, match_tags: &[String], ) -> anyhow::Result> { - let res = find_collect(T::coll().await, None, None) + let res = find_collect(T::coll(), None, None) .await .with_context(|| { format!("failed to pull {}s from mongo", T::resource_type()) @@ -555,7 +559,6 @@ pub async fn create( }; let resource_id = T::coll() - .await .insert_one(&resource) .await .with_context(|| { @@ -644,14 +647,9 @@ pub async fn update( let update_doc = flatten_document(doc! { "config": config_doc }); - update_one_by_id( - T::coll().await, - &id, - doc! { "$set": update_doc }, - None, - ) - .await - .context("failed to update resource on database")?; + update_one_by_id(T::coll(), &id, doc! { "$set": update_doc }, None) + .await + .context("failed to update resource on database")?; let mut update = make_update( resource_target::(id), @@ -707,7 +705,6 @@ pub async fn update_description( ) .await?; T::coll() - .await .update_one( id_or_name_filter(id_or_name), doc! { "$set": { "description": description } }, @@ -741,7 +738,6 @@ pub async fn update_tags( .flatten() .collect::>(); T::coll() - .await .update_one( id_or_name_filter(id_or_name), doc! { "$set": { "tags": tags } }, @@ -754,13 +750,67 @@ pub async fn remove_tag_from_all( tag_id: &str, ) -> anyhow::Result<()> { T::coll() - .await .update_many(doc! {}, doc! { "$pull": { "tags": tag_id } }) .await .context("failed to remove tag from resources")?; Ok(()) } +// ======= +// RENAME +// ======= + +pub async fn rename( + id_or_name: &str, + name: &str, + user: &User, +) -> anyhow::Result { + let resource = get_check_permissions::( + id_or_name, + user, + PermissionLevel::Write, + ) + .await?; + + let mut update = make_update( + resource_target::(resource.id.clone()), + T::rename_operation(), + user, + ); + + let name = to_komodo_name(name); + + update_one_by_id( + T::coll(), + &resource.id, + mungos::update::Update::Set( + doc! { "name": &name, "updated_at": komodo_timestamp() }, + ), + None, + ) + .await + .with_context(|| { + format!( + "Failed to update {ty} on db. This name may already be taken.", + ty = T::resource_type() + ) + })?; + + update.push_simple_log( + &format!("Rename {}", T::resource_type()), + format!( + "Renamed {ty} {id} from {prev_name} to {name}", + ty = T::resource_type(), + id = resource.id, + prev_name = resource.name + ), + ); + + update.finalize(); + update.id = add_update(update.clone()).await?; + Ok(update) +} + // ======= // DELETE // ======= @@ -790,7 +840,7 @@ pub async fn delete( delete_all_permissions_on_resource(target.clone()).await; remove_from_recently_viewed(target.clone()).await; - delete_one_by_id(T::coll().await, &resource.id, None) + delete_one_by_id(T::coll(), &resource.id, None) .await .with_context(|| { format!("failed to delete {} from database", T::resource_type()) diff --git a/bin/core/src/resource/procedure.rs b/bin/core/src/resource/procedure.rs index dd409b7e7..5e9ea15e9 100644 --- a/bin/core/src/resource/procedure.rs +++ b/bin/core/src/resource/procedure.rs @@ -45,8 +45,8 @@ impl super::KomodoResource for Procedure { ResourceTargetVariant::Procedure } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().procedures } @@ -115,11 +115,16 @@ impl super::KomodoResource for Procedure { } async fn post_update( - _updated: &Self, - _update: &mut Update, + updated: &Self, + update: &mut Update, ) -> anyhow::Result<()> { - refresh_procedure_state_cache().await; - Ok(()) + Self::post_create(updated, update).await + } + + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameProcedure } // DELETE diff --git a/bin/core/src/resource/repo.rs b/bin/core/src/resource/repo.rs index 96b272778..69b910eb2 100644 --- a/bin/core/src/resource/repo.rs +++ b/bin/core/src/resource/repo.rs @@ -11,6 +11,7 @@ use komodo_client::entities::{ }, resource::Resource, server::Server, + to_komodo_name, update::Update, user::User, Operation, ResourceTargetVariant, @@ -43,8 +44,8 @@ impl super::KomodoResource for Repo { ResourceTargetVariant::Repo } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().repos } @@ -132,6 +133,12 @@ impl super::KomodoResource for Repo { Ok(()) } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameRepo + } + // DELETE fn delete_operation() -> Operation { @@ -158,7 +165,11 @@ impl super::KomodoResource for Repo { match periphery .request(DeleteRepo { - name: repo.name.clone(), + name: if repo.config.path.is_empty() { + to_komodo_name(&repo.name) + } else { + repo.config.path.clone() + }, }) .await { diff --git a/bin/core/src/resource/server.rs b/bin/core/src/resource/server.rs index 5e05c97ef..6bd54f375 100644 --- a/bin/core/src/resource/server.rs +++ b/bin/core/src/resource/server.rs @@ -30,8 +30,8 @@ impl super::KomodoResource for Server { ResourceTargetVariant::Server } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().servers } @@ -115,6 +115,12 @@ impl super::KomodoResource for Server { Ok(()) } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameServer + } + // DELETE fn delete_operation() -> Operation { diff --git a/bin/core/src/resource/server_template.rs b/bin/core/src/resource/server_template.rs index ba5433cac..c54bfef69 100644 --- a/bin/core/src/resource/server_template.rs +++ b/bin/core/src/resource/server_template.rs @@ -29,8 +29,8 @@ impl super::KomodoResource for ServerTemplate { ResourceTargetVariant::ServerTemplate } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().server_templates } @@ -117,6 +117,12 @@ impl super::KomodoResource for ServerTemplate { Ok(()) } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameServerTemplate + } + // DELETE fn delete_operation() -> Operation { diff --git a/bin/core/src/resource/stack.rs b/bin/core/src/resource/stack.rs index 688ceab2f..7ecc42af9 100644 --- a/bin/core/src/resource/stack.rs +++ b/bin/core/src/resource/stack.rs @@ -44,8 +44,8 @@ impl super::KomodoResource for Stack { ResourceTargetVariant::Stack } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().stacks } @@ -172,7 +172,7 @@ impl super::KomodoResource for Stack { .await .inspect_err(|e| { warn!( - "Failed to get server for stack {} | {e:#}", + "Failed to get Server for Stack {} | {e:#}", created.name ) }) @@ -204,6 +204,12 @@ impl super::KomodoResource for Stack { Self::post_create(updated, update).await } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameStack + } + // DELETE fn delete_operation() -> Operation { diff --git a/bin/core/src/resource/sync.rs b/bin/core/src/resource/sync.rs index 1e386c89b..b7b856647 100644 --- a/bin/core/src/resource/sync.rs +++ b/bin/core/src/resource/sync.rs @@ -41,8 +41,8 @@ impl super::KomodoResource for ResourceSync { ResourceTargetVariant::ResourceSync } - async fn coll( - ) -> &'static Collection> { + fn coll() -> &'static Collection> + { &db_client().resource_syncs } @@ -117,6 +117,7 @@ impl super::KomodoResource for ResourceSync { format_serror(&e.context("The sync pending cache has failed to refresh. This is likely due to a misconfiguration of the sync").into()) ); }; + refresh_resource_sync_state_cache().await; Ok(()) } @@ -141,6 +142,12 @@ impl super::KomodoResource for ResourceSync { Self::post_create(updated, update).await } + // RENAME + + fn rename_operation() -> Operation { + Operation::RenameResourceSync + } + // DELETE fn delete_operation() -> Operation { diff --git a/bin/core/src/sync/execute.rs b/bin/core/src/sync/execute.rs index 3ff063dc7..8ab030357 100644 --- a/bin/core/src/sync/execute.rs +++ b/bin/core/src/sync/execute.rs @@ -32,7 +32,7 @@ pub async fn get_updates_for_execution< id_to_tags: &HashMap, match_tags: &[String], ) -> anyhow::Result> { - let map = find_collect(Resource::coll().await, None, None) + let map = find_collect(Resource::coll(), None, None) .await .context("failed to get resources from db")? .into_iter() diff --git a/bin/core/src/sync/view.rs b/bin/core/src/sync/view.rs index 6452c3b6c..fe4260f10 100644 --- a/bin/core/src/sync/view.rs +++ b/bin/core/src/sync/view.rs @@ -22,7 +22,7 @@ pub async fn push_updates_for_view( match_tags: &[String], diffs: &mut Vec, ) -> anyhow::Result<()> { - let current_map = find_collect(Resource::coll().await, None, None) + let current_map = find_collect(Resource::coll(), None, None) .await .context("failed to get resources from db")? .into_iter() diff --git a/bin/periphery/src/api/git.rs b/bin/periphery/src/api/git.rs index 86faf358d..768bd3611 100644 --- a/bin/periphery/src/api/git.rs +++ b/bin/periphery/src/api/git.rs @@ -1,13 +1,12 @@ use anyhow::{anyhow, Context}; use git::GitRes; -use komodo_client::entities::{ - to_komodo_name, update::Log, CloneArgs, LatestCommit, -}; +use komodo_client::entities::{update::Log, CloneArgs, LatestCommit}; use periphery_client::api::git::{ CloneRepo, DeleteRepo, GetLatestCommit, PullOrCloneRepo, PullRepo, - RepoActionResponse, + RenameRepo, RepoActionResponse, }; use resolver_api::Resolve; +use tokio::fs; use crate::{config::periphery_config, State}; @@ -207,6 +206,31 @@ impl Resolve for State { // +impl Resolve for State { + #[instrument(name = "RenameRepo", skip(self))] + async fn resolve( + &self, + RenameRepo { + curr_name, + new_name, + }: RenameRepo, + _: (), + ) -> anyhow::Result { + let renamed = fs::rename( + periphery_config().repo_dir.join(&curr_name), + periphery_config().repo_dir.join(&new_name), + ) + .await; + let msg = match renamed { + Ok(_) => format!("Renamed Repo directory on Server"), + Err(_) => format!("No Repo cloned at {curr_name} to rename"), + }; + Ok(Log::simple("Rename Repo on Server", msg)) + } +} + +// + impl Resolve for State { #[instrument(name = "DeleteRepo", skip(self))] async fn resolve( @@ -214,14 +238,15 @@ impl Resolve for State { DeleteRepo { name }: DeleteRepo, _: (), ) -> anyhow::Result { - let name = to_komodo_name(&name); - let deleted = std::fs::remove_dir_all( - periphery_config().repo_dir.join(&name), - ); + // If using custom clone path, it will be passed by core instead of name. + // So the join will resolve to just the absolute path. + let deleted = + fs::remove_dir_all(periphery_config().repo_dir.join(&name)) + .await; let msg = match deleted { - Ok(_) => format!("deleted repo {name}"), - Err(_) => format!("no repo at {name} to delete"), + Ok(_) => format!("Deleted Repo {name}"), + Err(_) => format!("No Repo at {name} to delete"), }; - Ok(Log::simple("delete repo", msg)) + Ok(Log::simple("Delete Repo on Host", msg)) } } diff --git a/bin/periphery/src/api/mod.rs b/bin/periphery/src/api/mod.rs index 8ef26f894..e7e7de567 100644 --- a/bin/periphery/src/api/mod.rs +++ b/bin/periphery/src/api/mod.rs @@ -66,6 +66,7 @@ pub enum PeripheryRequest { // Repo (Write) CloneRepo(CloneRepo), PullRepo(PullRepo), + RenameRepo(RenameRepo), DeleteRepo(DeleteRepo), // Build diff --git a/client/core/rs/src/api/write/action.rs b/client/core/rs/src/api/write/action.rs index fc876734d..47768ad43 100644 --- a/client/core/rs/src/api/write/action.rs +++ b/client/core/rs/src/api/write/action.rs @@ -5,6 +5,7 @@ use typeshare::typeshare; use crate::entities::{ action::{Action, _PartialActionConfig}, + update::Update, NoData, }; @@ -23,6 +24,7 @@ pub struct CreateAction { /// The name given to newly created action. pub name: String, /// Optional partial config to initialize the action with. + #[serde(default)] pub config: _PartialActionConfig, } @@ -81,6 +83,23 @@ pub struct UpdateAction { pub config: _PartialActionConfig, } +// + +/// Rename the Action at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameAction { + /// The id or name of the Action to rename. + pub id: String, + /// The new name. + pub name: String, +} + /// Create a webhook on the github action attached to the Action resource. /// passed in request. Response: [CreateActionWebhookResponse] #[typeshare] diff --git a/client/core/rs/src/api/write/alerter.rs b/client/core/rs/src/api/write/alerter.rs index 3558dc63d..7072f813b 100644 --- a/client/core/rs/src/api/write/alerter.rs +++ b/client/core/rs/src/api/write/alerter.rs @@ -3,7 +3,10 @@ use resolver_api::derive::Request; use serde::{Deserialize, Serialize}; use typeshare::typeshare; -use crate::entities::alerter::{Alerter, _PartialAlerterConfig}; +use crate::entities::{ + alerter::{Alerter, _PartialAlerterConfig}, + update::Update, +}; use super::KomodoWriteRequest; @@ -20,6 +23,7 @@ pub struct CreateAlerter { /// The name given to newly created alerter. pub name: String, /// Optional partial config to initialize the alerter with. + #[serde(default)] pub config: _PartialAlerterConfig, } @@ -75,3 +79,20 @@ pub struct UpdateAlerter { /// The partial config update to apply. pub config: _PartialAlerterConfig, } + +// + +/// Rename the Alerter at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameAlerter { + /// The id or name of the Alerter to rename. + pub id: String, + /// The new name. + pub name: String, +} diff --git a/client/core/rs/src/api/write/build.rs b/client/core/rs/src/api/write/build.rs index 3778d80a7..c293787b5 100644 --- a/client/core/rs/src/api/write/build.rs +++ b/client/core/rs/src/api/write/build.rs @@ -5,6 +5,7 @@ use typeshare::typeshare; use crate::entities::{ build::{Build, _PartialBuildConfig}, + update::Update, NoData, }; @@ -23,6 +24,7 @@ pub struct CreateBuild { /// The name given to newly created build. pub name: String, /// Optional partial config to initialize the build with. + #[serde(default)] pub config: _PartialBuildConfig, } @@ -83,6 +85,23 @@ pub struct UpdateBuild { // +/// Rename the Build at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameBuild { + /// The id or name of the Build to rename. + pub id: String, + /// The new name. + pub name: String, +} + +// + /// Trigger a refresh of the cached latest hash and message. #[typeshare] #[derive( diff --git a/client/core/rs/src/api/write/builder.rs b/client/core/rs/src/api/write/builder.rs index 1e38f7234..bac758472 100644 --- a/client/core/rs/src/api/write/builder.rs +++ b/client/core/rs/src/api/write/builder.rs @@ -3,7 +3,7 @@ use resolver_api::derive::Request; use serde::{Deserialize, Serialize}; use typeshare::typeshare; -use crate::entities::builder::{Builder, PartialBuilderConfig}; +use crate::entities::{builder::{Builder, PartialBuilderConfig}, update::Update}; use super::KomodoWriteRequest; @@ -20,6 +20,7 @@ pub struct CreateBuilder { /// The name given to newly created builder. pub name: String, /// Optional partial config to initialize the builder with. + #[serde(default)] pub config: PartialBuilderConfig, } @@ -77,3 +78,20 @@ pub struct UpdateBuilder { /// The partial config update to apply. pub config: PartialBuilderConfig, } + +// + +/// Rename the Builder at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameBuilder { + /// The id or name of the Builder to rename. + pub id: String, + /// The new name. + pub name: String, +} \ No newline at end of file diff --git a/client/core/rs/src/api/write/deployment.rs b/client/core/rs/src/api/write/deployment.rs index 9eb1abd11..85bb41ccf 100644 --- a/client/core/rs/src/api/write/deployment.rs +++ b/client/core/rs/src/api/write/deployment.rs @@ -23,6 +23,7 @@ pub struct CreateDeployment { /// The name given to newly created deployment. pub name: String, /// Optional partial config to initialize the deployment with. + #[serde(default)] pub config: _PartialDeploymentConfig, } diff --git a/client/core/rs/src/api/write/procedure.rs b/client/core/rs/src/api/write/procedure.rs index 125624b7f..789a43c28 100644 --- a/client/core/rs/src/api/write/procedure.rs +++ b/client/core/rs/src/api/write/procedure.rs @@ -3,9 +3,9 @@ use resolver_api::derive::Request; use serde::{Deserialize, Serialize}; use typeshare::typeshare; -use crate::entities::procedure::{ +use crate::entities::{procedure::{ Procedure, _PartialProcedureConfig, -}; +}, update::Update}; use super::KomodoWriteRequest; @@ -22,6 +22,7 @@ pub struct CreateProcedure { /// The name given to newly created build. pub name: String, /// Optional partial config to initialize the procedure with. + #[serde(default)] pub config: _PartialProcedureConfig, } @@ -91,3 +92,20 @@ pub struct UpdateProcedure { #[typeshare] pub type UpdateProcedureResponse = Procedure; + +// + +/// Rename the Procedure at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameProcedure { + /// The id or name of the Procedure to rename. + pub id: String, + /// The new name. + pub name: String, +} \ No newline at end of file diff --git a/client/core/rs/src/api/write/repo.rs b/client/core/rs/src/api/write/repo.rs index d3bcfd2aa..84eafb699 100644 --- a/client/core/rs/src/api/write/repo.rs +++ b/client/core/rs/src/api/write/repo.rs @@ -4,8 +4,7 @@ use serde::{Deserialize, Serialize}; use typeshare::typeshare; use crate::entities::{ - repo::{Repo, _PartialRepoConfig}, - NoData, + repo::{Repo, _PartialRepoConfig}, update::Update, NoData }; use super::KomodoWriteRequest; @@ -23,6 +22,7 @@ pub struct CreateRepo { /// The name given to newly created repo. pub name: String, /// Optional partial config to initialize the repo with. + #[serde(default)] pub config: _PartialRepoConfig, } @@ -86,6 +86,23 @@ pub struct UpdateRepo { // +/// Rename the Repo at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameRepo { + /// The id or name of the Repo to rename. + pub id: String, + /// The new name. + pub name: String, +} + +// + /// Trigger a refresh of the cached latest hash and message. #[typeshare] #[derive( diff --git a/client/core/rs/src/api/write/server.rs b/client/core/rs/src/api/write/server.rs index 4f3a33bee..f4dce6ece 100644 --- a/client/core/rs/src/api/write/server.rs +++ b/client/core/rs/src/api/write/server.rs @@ -23,6 +23,7 @@ pub struct CreateServer { /// The name given to newly created server. pub name: String, /// Optional partial config to initialize the server with. + #[serde(default)] pub config: _PartialServerConfig, } @@ -58,7 +59,7 @@ pub struct DeleteServer { #[empty_traits(KomodoWriteRequest)] #[response(Server)] pub struct UpdateServer { - /// The id of the server to update. + /// The id or name of the server to update. pub id: String, /// The partial config update to apply. pub config: _PartialServerConfig, @@ -66,7 +67,8 @@ pub struct UpdateServer { // -/// Rename the server at id to the given name. Response: [Update]. +/// Rename an Server to the given name. +/// Response: [Update]. #[typeshare] #[derive( Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, @@ -74,7 +76,7 @@ pub struct UpdateServer { #[empty_traits(KomodoWriteRequest)] #[response(Update)] pub struct RenameServer { - /// The id of the server to rename. + /// The id or name of the Server to rename. pub id: String, /// The new name. pub name: String, @@ -83,7 +85,9 @@ pub struct RenameServer { // /// Create a docker network on the server. -/// Respone: [Update] +/// Response: [Update] +/// +/// `docker network create {name}` #[typeshare] #[derive( Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, @@ -91,7 +95,7 @@ pub struct RenameServer { #[empty_traits(KomodoWriteRequest)] #[response(Update)] pub struct CreateNetwork { - /// Id or name + /// Server Id or name pub server: String, /// The name of the network to create. pub name: String, diff --git a/client/core/rs/src/api/write/server_template.rs b/client/core/rs/src/api/write/server_template.rs index 6e2feae8d..594658357 100644 --- a/client/core/rs/src/api/write/server_template.rs +++ b/client/core/rs/src/api/write/server_template.rs @@ -3,9 +3,9 @@ use resolver_api::derive::Request; use serde::{Deserialize, Serialize}; use typeshare::typeshare; -use crate::entities::server_template::{ +use crate::entities::{server_template::{ PartialServerTemplateConfig, ServerTemplate, -}; +}, update::Update}; use super::KomodoWriteRequest; @@ -22,6 +22,7 @@ pub struct CreateServerTemplate { /// The name given to newly created server template. pub name: String, /// Optional partial config to initialize the server template with. + #[serde(default)] pub config: PartialServerTemplateConfig, } @@ -79,3 +80,20 @@ pub struct UpdateServerTemplate { /// The partial config update to apply. pub config: PartialServerTemplateConfig, } + +// + +/// Rename the ServerTemplate at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameServerTemplate { + /// The id or name of the ServerTemplate to rename. + pub id: String, + /// The new name. + pub name: String, +} \ No newline at end of file diff --git a/client/core/rs/src/api/write/stack.rs b/client/core/rs/src/api/write/stack.rs index 8ef5672b0..8cbd0e1ca 100644 --- a/client/core/rs/src/api/write/stack.rs +++ b/client/core/rs/src/api/write/stack.rs @@ -24,6 +24,7 @@ pub struct CreateStack { /// The name given to newly created stack. pub name: String, /// Optional partial config to initialize the stack with. + #[serde(default)] pub config: _PartialStackConfig, } diff --git a/client/core/rs/src/api/write/sync.rs b/client/core/rs/src/api/write/sync.rs index 1f9a76691..04816e7bc 100644 --- a/client/core/rs/src/api/write/sync.rs +++ b/client/core/rs/src/api/write/sync.rs @@ -25,6 +25,7 @@ pub struct CreateResourceSync { /// The name given to newly created sync. pub name: String, /// Optional partial config to initialize the sync with. + #[serde(default)] pub config: _PartialResourceSyncConfig, } @@ -85,6 +86,23 @@ pub struct UpdateResourceSync { // +/// Rename the ResourceSync at id to the given name. +/// Response: [Update]. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Request, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(Update)] +pub struct RenameResourceSync { + /// The id or name of the ResourceSync to rename. + pub id: String, + /// The new name. + pub name: String, +} + +// + /// Trigger a refresh of the computed diff logs for view. Response: [ResourceSync] #[typeshare] #[derive( diff --git a/client/core/rs/src/entities/mod.rs b/client/core/rs/src/entities/mod.rs index 734b8c32f..a42aea084 100644 --- a/client/core/rs/src/entities/mod.rs +++ b/client/core/rs/src/entities/mod.rs @@ -695,6 +695,7 @@ pub enum Operation { // deployment CreateDeployment, UpdateDeployment, + RenameDeployment, DeleteDeployment, Deploy, StartDeployment, @@ -703,11 +704,11 @@ pub enum Operation { UnpauseDeployment, StopDeployment, DestroyDeployment, - RenameDeployment, // build CreateBuild, UpdateBuild, + RenameBuild, DeleteBuild, RunBuild, CancelBuild, @@ -715,6 +716,7 @@ pub enum Operation { // repo CreateRepo, UpdateRepo, + RenameRepo, DeleteRepo, CloneRepo, PullRepo, @@ -724,34 +726,40 @@ pub enum Operation { // procedure CreateProcedure, UpdateProcedure, + RenameProcedure, DeleteProcedure, RunProcedure, // action CreateAction, UpdateAction, + RenameAction, DeleteAction, RunAction, // builder CreateBuilder, UpdateBuilder, + RenameBuilder, DeleteBuilder, // alerter CreateAlerter, UpdateAlerter, + RenameAlerter, DeleteAlerter, // server template CreateServerTemplate, UpdateServerTemplate, + RenameServerTemplate, DeleteServerTemplate, LaunchServer, // sync CreateResourceSync, UpdateResourceSync, + RenameResourceSync, DeleteResourceSync, WriteSyncContents, CommitSync, diff --git a/client/core/rs/src/entities/repo.rs b/client/core/rs/src/entities/repo.rs index 3cbb0cc9b..872e220f8 100644 --- a/client/core/rs/src/entities/repo.rs +++ b/client/core/rs/src/entities/repo.rs @@ -277,12 +277,14 @@ impl Default for RepoConfig { #[typeshare] #[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)] pub struct RepoActionState { - /// Whether repo currently cloning + /// Whether Repo currently cloning on the attached Server pub cloning: bool, - /// Whether repo currently pulling + /// Whether Repo currently pulling on the attached Server pub pulling: bool, - /// Whether repo currently building, using the attached builder. + /// Whether Repo currently building using the attached Builder. pub building: bool, + /// Whether Repo currently renaming. + pub renaming: bool, } #[typeshare] diff --git a/client/core/ts/src/responses.ts b/client/core/ts/src/responses.ts index ba215b100..0b20ccd18 100644 --- a/client/core/ts/src/responses.ts +++ b/client/core/ts/src/responses.ts @@ -228,6 +228,7 @@ export type WriteResponses = { CopyBuild: Types.Build; DeleteBuild: Types.Build; UpdateBuild: Types.Build; + RenameBuild: Types.Update; RefreshBuildCache: Types.NoData; CreateBuildWebhook: Types.CreateBuildWebhookResponse; DeleteBuildWebhook: Types.DeleteBuildWebhookResponse; @@ -237,18 +238,21 @@ export type WriteResponses = { CopyBuilder: Types.Builder; DeleteBuilder: Types.Builder; UpdateBuilder: Types.Builder; + RenameBuilder: Types.Update; // ==== SERVER TEMPLATE ==== CreateServerTemplate: Types.ServerTemplate; CopyServerTemplate: Types.ServerTemplate; DeleteServerTemplate: Types.ServerTemplate; UpdateServerTemplate: Types.ServerTemplate; + RenameServerTemplate: Types.Update; // ==== REPO ==== CreateRepo: Types.Repo; CopyRepo: Types.Repo; DeleteRepo: Types.Repo; UpdateRepo: Types.Repo; + RenameRepo: Types.Update; RefreshRepoCache: Types.NoData; CreateRepoWebhook: Types.CreateRepoWebhookResponse; DeleteRepoWebhook: Types.DeleteRepoWebhookResponse; @@ -258,24 +262,28 @@ export type WriteResponses = { CopyAlerter: Types.Alerter; DeleteAlerter: Types.Alerter; UpdateAlerter: Types.Alerter; + RenameAlerter: Types.Update; // ==== PROCEDURE ==== CreateProcedure: Types.Procedure; CopyProcedure: Types.Procedure; DeleteProcedure: Types.Procedure; UpdateProcedure: Types.Procedure; + RenameProcedure: Types.Update; // ==== ACTION ==== CreateAction: Types.Action; CopyAction: Types.Action; DeleteAction: Types.Action; UpdateAction: Types.Action; + RenameAction: Types.Update; // ==== SYNC ==== CreateResourceSync: Types.ResourceSync; CopyResourceSync: Types.ResourceSync; DeleteResourceSync: Types.ResourceSync; UpdateResourceSync: Types.ResourceSync; + RenameResourceSync: Types.Update; CommitSync: Types.ResourceSync; WriteSyncFileContents: Types.Update; RefreshResourceSyncPending: Types.ResourceSync; diff --git a/client/core/ts/src/types.ts b/client/core/ts/src/types.ts index 203b0b26f..af0bcc778 100644 --- a/client/core/ts/src/types.ts +++ b/client/core/ts/src/types.ts @@ -1097,12 +1097,14 @@ export type GetProcedureActionStateResponse = ProcedureActionState; export type GetProcedureResponse = Procedure; export interface RepoActionState { - /** Whether repo currently cloning */ + /** Whether Repo currently cloning on the attached Server */ cloning: boolean; - /** Whether repo currently pulling */ + /** Whether Repo currently pulling on the attached Server */ pulling: boolean; - /** Whether repo currently building, using the attached builder. */ + /** Whether Repo currently building using the attached Builder. */ building: boolean; + /** Whether Repo currently renaming. */ + renaming: boolean; } export type GetRepoActionStateResponse = RepoActionState; @@ -1808,6 +1810,7 @@ export enum Operation { StopStackService = "StopStackService", CreateDeployment = "CreateDeployment", UpdateDeployment = "UpdateDeployment", + RenameDeployment = "RenameDeployment", DeleteDeployment = "DeleteDeployment", Deploy = "Deploy", StartDeployment = "StartDeployment", @@ -1816,14 +1819,15 @@ export enum Operation { UnpauseDeployment = "UnpauseDeployment", StopDeployment = "StopDeployment", DestroyDeployment = "DestroyDeployment", - RenameDeployment = "RenameDeployment", CreateBuild = "CreateBuild", UpdateBuild = "UpdateBuild", + RenameBuild = "RenameBuild", DeleteBuild = "DeleteBuild", RunBuild = "RunBuild", CancelBuild = "CancelBuild", CreateRepo = "CreateRepo", UpdateRepo = "UpdateRepo", + RenameRepo = "RenameRepo", DeleteRepo = "DeleteRepo", CloneRepo = "CloneRepo", PullRepo = "PullRepo", @@ -1831,24 +1835,30 @@ export enum Operation { CancelRepoBuild = "CancelRepoBuild", CreateProcedure = "CreateProcedure", UpdateProcedure = "UpdateProcedure", + RenameProcedure = "RenameProcedure", DeleteProcedure = "DeleteProcedure", RunProcedure = "RunProcedure", CreateAction = "CreateAction", UpdateAction = "UpdateAction", + RenameAction = "RenameAction", DeleteAction = "DeleteAction", RunAction = "RunAction", CreateBuilder = "CreateBuilder", UpdateBuilder = "UpdateBuilder", + RenameBuilder = "RenameBuilder", DeleteBuilder = "DeleteBuilder", CreateAlerter = "CreateAlerter", UpdateAlerter = "UpdateAlerter", + RenameAlerter = "RenameAlerter", DeleteAlerter = "DeleteAlerter", CreateServerTemplate = "CreateServerTemplate", UpdateServerTemplate = "UpdateServerTemplate", + RenameServerTemplate = "RenameServerTemplate", DeleteServerTemplate = "DeleteServerTemplate", LaunchServer = "LaunchServer", CreateResourceSync = "CreateResourceSync", UpdateResourceSync = "UpdateResourceSync", + RenameResourceSync = "RenameResourceSync", DeleteResourceSync = "DeleteResourceSync", WriteSyncContents = "WriteSyncContents", CommitSync = "CommitSync", @@ -3722,7 +3732,7 @@ export interface CreateAction { /** The name given to newly created action. */ name: string; /** Optional partial config to initialize the action with. */ - config: _PartialActionConfig; + config?: _PartialActionConfig; } /** @@ -3739,7 +3749,7 @@ export interface CreateAlerter { /** The name given to newly created alerter. */ name: string; /** Optional partial config to initialize the alerter with. */ - config: _PartialAlerterConfig; + config?: _PartialAlerterConfig; } /** @@ -3780,7 +3790,7 @@ export interface CreateBuild { /** The name given to newly created build. */ name: string; /** Optional partial config to initialize the build with. */ - config: _PartialBuildConfig; + config?: _PartialBuildConfig; } /** @@ -3802,7 +3812,7 @@ export interface CreateBuilder { /** The name given to newly created builder. */ name: string; /** Optional partial config to initialize the builder with. */ - config: PartialBuilderConfig; + config?: PartialBuilderConfig; } /** Create a deployment. Response: [Deployment]. */ @@ -3810,7 +3820,7 @@ export interface CreateDeployment { /** The name given to newly created deployment. */ name: string; /** Optional partial config to initialize the deployment with. */ - config: _PartialDeploymentConfig; + config?: _PartialDeploymentConfig; } /** @@ -3852,10 +3862,12 @@ export interface CreateLocalUser { /** * Create a docker network on the server. - * Respone: [Update] + * Response: [Update] + * + * `docker network create {name}` */ export interface CreateNetwork { - /** Id or name */ + /** Server Id or name */ server: string; /** The name of the network to create. */ name: string; @@ -3866,7 +3878,7 @@ export interface CreateProcedure { /** The name given to newly created build. */ name: string; /** Optional partial config to initialize the procedure with. */ - config: _PartialProcedureConfig; + config?: _PartialProcedureConfig; } /** Create a repo. Response: [Repo]. */ @@ -3874,7 +3886,7 @@ export interface CreateRepo { /** The name given to newly created repo. */ name: string; /** Optional partial config to initialize the repo with. */ - config: _PartialRepoConfig; + config?: _PartialRepoConfig; } export enum RepoWebhookAction { @@ -3899,7 +3911,7 @@ export interface CreateResourceSync { /** The name given to newly created sync. */ name: string; /** Optional partial config to initialize the sync with. */ - config: _PartialResourceSyncConfig; + config?: _PartialResourceSyncConfig; } /** Create a server. Response: [Server]. */ @@ -3907,7 +3919,7 @@ export interface CreateServer { /** The name given to newly created server. */ name: string; /** Optional partial config to initialize the server with. */ - config: _PartialServerConfig; + config?: _PartialServerConfig; } export type PartialServerTemplateConfig = @@ -3919,7 +3931,7 @@ export interface CreateServerTemplate { /** The name given to newly created server template. */ name: string; /** Optional partial config to initialize the server template with. */ - config: PartialServerTemplateConfig; + config?: PartialServerTemplateConfig; } /** @@ -3938,7 +3950,7 @@ export interface CreateStack { /** The name given to newly created stack. */ name: string; /** Optional partial config to initialize the stack with. */ - config: _PartialStackConfig; + config?: _PartialStackConfig; } export enum StackWebhookAction { @@ -6064,6 +6076,50 @@ export interface RemoveUserFromUserGroup { user: string; } +/** + * Rename the Action at id to the given name. + * Response: [Update]. + */ +export interface RenameAction { + /** The id or name of the Action to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename the Alerter at id to the given name. + * Response: [Update]. + */ +export interface RenameAlerter { + /** The id or name of the Alerter to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename the Build at id to the given name. + * Response: [Update]. + */ +export interface RenameBuild { + /** The id or name of the Build to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename the Builder at id to the given name. + * Response: [Update]. + */ +export interface RenameBuilder { + /** The id or name of the Builder to rename. */ + id: string; + /** The new name. */ + name: string; +} + /** * Rename the deployment at id to the given name. Response: [Update]. * @@ -6077,9 +6133,56 @@ export interface RenameDeployment { name: string; } -/** Rename the server at id to the given name. Response: [Update]. */ +/** + * Rename the Procedure at id to the given name. + * Response: [Update]. + */ +export interface RenameProcedure { + /** The id or name of the Procedure to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename the Repo at id to the given name. + * Response: [Update]. + */ +export interface RenameRepo { + /** The id or name of the Repo to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename the ResourceSync at id to the given name. + * Response: [Update]. + */ +export interface RenameResourceSync { + /** The id or name of the ResourceSync to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename an Server to the given name. + * Response: [Update]. + */ export interface RenameServer { - /** The id of the server to rename. */ + /** The id or name of the Server to rename. */ + id: string; + /** The new name. */ + name: string; +} + +/** + * Rename the ServerTemplate at id to the given name. + * Response: [Update]. + */ +export interface RenameServerTemplate { + /** The id or name of the ServerTemplate to rename. */ id: string; /** The new name. */ name: string; @@ -6666,7 +6769,7 @@ export interface UpdateResourceSync { * field changes occur from out of date local state. */ export interface UpdateServer { - /** The id of the server to update. */ + /** The id or name of the server to update. */ id: string; /** The partial config update to apply. */ config: _PartialServerConfig; @@ -7046,6 +7149,7 @@ export type WriteRequest = | { type: "CopyBuild", params: CopyBuild } | { type: "DeleteBuild", params: DeleteBuild } | { type: "UpdateBuild", params: UpdateBuild } + | { type: "RenameBuild", params: RenameBuild } | { type: "RefreshBuildCache", params: RefreshBuildCache } | { type: "CreateBuildWebhook", params: CreateBuildWebhook } | { type: "DeleteBuildWebhook", params: DeleteBuildWebhook } @@ -7053,14 +7157,17 @@ export type WriteRequest = | { type: "CopyBuilder", params: CopyBuilder } | { type: "DeleteBuilder", params: DeleteBuilder } | { type: "UpdateBuilder", params: UpdateBuilder } + | { type: "RenameBuilder", params: RenameBuilder } | { type: "CreateServerTemplate", params: CreateServerTemplate } | { type: "CopyServerTemplate", params: CopyServerTemplate } | { type: "DeleteServerTemplate", params: DeleteServerTemplate } | { type: "UpdateServerTemplate", params: UpdateServerTemplate } + | { type: "RenameServerTemplate", params: RenameServerTemplate } | { type: "CreateRepo", params: CreateRepo } | { type: "CopyRepo", params: CopyRepo } | { type: "DeleteRepo", params: DeleteRepo } | { type: "UpdateRepo", params: UpdateRepo } + | { type: "RenameRepo", params: RenameRepo } | { type: "RefreshRepoCache", params: RefreshRepoCache } | { type: "CreateRepoWebhook", params: CreateRepoWebhook } | { type: "DeleteRepoWebhook", params: DeleteRepoWebhook } @@ -7068,18 +7175,22 @@ export type WriteRequest = | { type: "CopyAlerter", params: CopyAlerter } | { type: "DeleteAlerter", params: DeleteAlerter } | { type: "UpdateAlerter", params: UpdateAlerter } + | { type: "RenameAlerter", params: RenameAlerter } | { type: "CreateProcedure", params: CreateProcedure } | { type: "CopyProcedure", params: CopyProcedure } | { type: "DeleteProcedure", params: DeleteProcedure } | { type: "UpdateProcedure", params: UpdateProcedure } + | { type: "RenameProcedure", params: RenameProcedure } | { type: "CreateAction", params: CreateAction } | { type: "CopyAction", params: CopyAction } | { type: "DeleteAction", params: DeleteAction } | { type: "UpdateAction", params: UpdateAction } + | { type: "RenameAction", params: RenameAction } | { type: "CreateResourceSync", params: CreateResourceSync } | { type: "CopyResourceSync", params: CopyResourceSync } | { type: "DeleteResourceSync", params: DeleteResourceSync } | { type: "UpdateResourceSync", params: UpdateResourceSync } + | { type: "RenameResourceSync", params: RenameResourceSync } | { type: "WriteSyncFileContents", params: WriteSyncFileContents } | { type: "CommitSync", params: CommitSync } | { type: "RefreshResourceSyncPending", params: RefreshResourceSyncPending } diff --git a/client/periphery/rs/src/api/git.rs b/client/periphery/rs/src/api/git.rs index 94a00b80b..3302da1c1 100644 --- a/client/periphery/rs/src/api/git.rs +++ b/client/periphery/rs/src/api/git.rs @@ -86,6 +86,15 @@ pub struct RepoActionResponse { // +#[derive(Serialize, Deserialize, Debug, Clone, Request)] +#[response(Log)] +pub struct RenameRepo { + pub curr_name: String, + pub new_name: String, +} + +// + #[derive(Serialize, Deserialize, Debug, Clone, Request)] #[response(Log)] pub struct DeleteRepo { diff --git a/frontend/public/client/responses.d.ts b/frontend/public/client/responses.d.ts index 2c64496c5..943731c7c 100644 --- a/frontend/public/client/responses.d.ts +++ b/frontend/public/client/responses.d.ts @@ -167,6 +167,7 @@ export type WriteResponses = { CopyBuild: Types.Build; DeleteBuild: Types.Build; UpdateBuild: Types.Build; + RenameBuild: Types.Update; RefreshBuildCache: Types.NoData; CreateBuildWebhook: Types.CreateBuildWebhookResponse; DeleteBuildWebhook: Types.DeleteBuildWebhookResponse; @@ -174,14 +175,17 @@ export type WriteResponses = { CopyBuilder: Types.Builder; DeleteBuilder: Types.Builder; UpdateBuilder: Types.Builder; + RenameBuilder: Types.Update; CreateServerTemplate: Types.ServerTemplate; CopyServerTemplate: Types.ServerTemplate; DeleteServerTemplate: Types.ServerTemplate; UpdateServerTemplate: Types.ServerTemplate; + RenameServerTemplate: Types.Update; CreateRepo: Types.Repo; CopyRepo: Types.Repo; DeleteRepo: Types.Repo; UpdateRepo: Types.Repo; + RenameRepo: Types.Update; RefreshRepoCache: Types.NoData; CreateRepoWebhook: Types.CreateRepoWebhookResponse; DeleteRepoWebhook: Types.DeleteRepoWebhookResponse; @@ -189,18 +193,22 @@ export type WriteResponses = { CopyAlerter: Types.Alerter; DeleteAlerter: Types.Alerter; UpdateAlerter: Types.Alerter; + RenameAlerter: Types.Update; CreateProcedure: Types.Procedure; CopyProcedure: Types.Procedure; DeleteProcedure: Types.Procedure; UpdateProcedure: Types.Procedure; + RenameProcedure: Types.Update; CreateAction: Types.Action; CopyAction: Types.Action; DeleteAction: Types.Action; UpdateAction: Types.Action; + RenameAction: Types.Update; CreateResourceSync: Types.ResourceSync; CopyResourceSync: Types.ResourceSync; DeleteResourceSync: Types.ResourceSync; UpdateResourceSync: Types.ResourceSync; + RenameResourceSync: Types.Update; CommitSync: Types.ResourceSync; WriteSyncFileContents: Types.Update; RefreshResourceSyncPending: Types.ResourceSync; diff --git a/frontend/public/client/types.d.ts b/frontend/public/client/types.d.ts index 4e7860f8c..558419759 100644 --- a/frontend/public/client/types.d.ts +++ b/frontend/public/client/types.d.ts @@ -1162,12 +1162,14 @@ export interface ProcedureActionState { export type GetProcedureActionStateResponse = ProcedureActionState; export type GetProcedureResponse = Procedure; export interface RepoActionState { - /** Whether repo currently cloning */ + /** Whether Repo currently cloning on the attached Server */ cloning: boolean; - /** Whether repo currently pulling */ + /** Whether Repo currently pulling on the attached Server */ pulling: boolean; - /** Whether repo currently building, using the attached builder. */ + /** Whether Repo currently building using the attached Builder. */ building: boolean; + /** Whether Repo currently renaming. */ + renaming: boolean; } export type GetRepoActionStateResponse = RepoActionState; export interface RepoConfig { @@ -1845,6 +1847,7 @@ export declare enum Operation { StopStackService = "StopStackService", CreateDeployment = "CreateDeployment", UpdateDeployment = "UpdateDeployment", + RenameDeployment = "RenameDeployment", DeleteDeployment = "DeleteDeployment", Deploy = "Deploy", StartDeployment = "StartDeployment", @@ -1853,14 +1856,15 @@ export declare enum Operation { UnpauseDeployment = "UnpauseDeployment", StopDeployment = "StopDeployment", DestroyDeployment = "DestroyDeployment", - RenameDeployment = "RenameDeployment", CreateBuild = "CreateBuild", UpdateBuild = "UpdateBuild", + RenameBuild = "RenameBuild", DeleteBuild = "DeleteBuild", RunBuild = "RunBuild", CancelBuild = "CancelBuild", CreateRepo = "CreateRepo", UpdateRepo = "UpdateRepo", + RenameRepo = "RenameRepo", DeleteRepo = "DeleteRepo", CloneRepo = "CloneRepo", PullRepo = "PullRepo", @@ -1868,24 +1872,30 @@ export declare enum Operation { CancelRepoBuild = "CancelRepoBuild", CreateProcedure = "CreateProcedure", UpdateProcedure = "UpdateProcedure", + RenameProcedure = "RenameProcedure", DeleteProcedure = "DeleteProcedure", RunProcedure = "RunProcedure", CreateAction = "CreateAction", UpdateAction = "UpdateAction", + RenameAction = "RenameAction", DeleteAction = "DeleteAction", RunAction = "RunAction", CreateBuilder = "CreateBuilder", UpdateBuilder = "UpdateBuilder", + RenameBuilder = "RenameBuilder", DeleteBuilder = "DeleteBuilder", CreateAlerter = "CreateAlerter", UpdateAlerter = "UpdateAlerter", + RenameAlerter = "RenameAlerter", DeleteAlerter = "DeleteAlerter", CreateServerTemplate = "CreateServerTemplate", UpdateServerTemplate = "UpdateServerTemplate", + RenameServerTemplate = "RenameServerTemplate", DeleteServerTemplate = "DeleteServerTemplate", LaunchServer = "LaunchServer", CreateResourceSync = "CreateResourceSync", UpdateResourceSync = "UpdateResourceSync", + RenameResourceSync = "RenameResourceSync", DeleteResourceSync = "DeleteResourceSync", WriteSyncContents = "WriteSyncContents", CommitSync = "CommitSync", @@ -3535,7 +3545,7 @@ export interface CreateAction { /** The name given to newly created action. */ name: string; /** Optional partial config to initialize the action with. */ - config: _PartialActionConfig; + config?: _PartialActionConfig; } /** * Create a webhook on the github action attached to the Action resource. @@ -3550,7 +3560,7 @@ export interface CreateAlerter { /** The name given to newly created alerter. */ name: string; /** Optional partial config to initialize the alerter with. */ - config: _PartialAlerterConfig; + config?: _PartialAlerterConfig; } /** * Create an api key for the calling user. @@ -3588,7 +3598,7 @@ export interface CreateBuild { /** The name given to newly created build. */ name: string; /** Optional partial config to initialize the build with. */ - config: _PartialBuildConfig; + config?: _PartialBuildConfig; } /** * Create a webhook on the github repo attached to the build @@ -3611,14 +3621,14 @@ export interface CreateBuilder { /** The name given to newly created builder. */ name: string; /** Optional partial config to initialize the builder with. */ - config: PartialBuilderConfig; + config?: PartialBuilderConfig; } /** Create a deployment. Response: [Deployment]. */ export interface CreateDeployment { /** The name given to newly created deployment. */ name: string; /** Optional partial config to initialize the deployment with. */ - config: _PartialDeploymentConfig; + config?: _PartialDeploymentConfig; } /** * **Admin only.** Create a docker registry account. @@ -3656,10 +3666,12 @@ export interface CreateLocalUser { } /** * Create a docker network on the server. - * Respone: [Update] + * Response: [Update] + * + * `docker network create {name}` */ export interface CreateNetwork { - /** Id or name */ + /** Server Id or name */ server: string; /** The name of the network to create. */ name: string; @@ -3669,14 +3681,14 @@ export interface CreateProcedure { /** The name given to newly created build. */ name: string; /** Optional partial config to initialize the procedure with. */ - config: _PartialProcedureConfig; + config?: _PartialProcedureConfig; } /** Create a repo. Response: [Repo]. */ export interface CreateRepo { /** The name given to newly created repo. */ name: string; /** Optional partial config to initialize the repo with. */ - config: _PartialRepoConfig; + config?: _PartialRepoConfig; } export declare enum RepoWebhookAction { Clone = "Clone", @@ -3698,14 +3710,14 @@ export interface CreateResourceSync { /** The name given to newly created sync. */ name: string; /** Optional partial config to initialize the sync with. */ - config: _PartialResourceSyncConfig; + config?: _PartialResourceSyncConfig; } /** Create a server. Response: [Server]. */ export interface CreateServer { /** The name given to newly created server. */ name: string; /** Optional partial config to initialize the server with. */ - config: _PartialServerConfig; + config?: _PartialServerConfig; } export type PartialServerTemplateConfig = { type: "Aws"; @@ -3719,7 +3731,7 @@ export interface CreateServerTemplate { /** The name given to newly created server template. */ name: string; /** Optional partial config to initialize the server template with. */ - config: PartialServerTemplateConfig; + config?: PartialServerTemplateConfig; } /** * **Admin only.** Create a service user. @@ -3736,7 +3748,7 @@ export interface CreateStack { /** The name given to newly created stack. */ name: string; /** Optional partial config to initialize the stack with. */ - config: _PartialStackConfig; + config?: _PartialStackConfig; } export declare enum StackWebhookAction { Refresh = "Refresh", @@ -5640,6 +5652,46 @@ export interface RemoveUserFromUserGroup { /** The id or username of the user to remove */ user: string; } +/** + * Rename the Action at id to the given name. + * Response: [Update]. + */ +export interface RenameAction { + /** The id or name of the Action to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename the Alerter at id to the given name. + * Response: [Update]. + */ +export interface RenameAlerter { + /** The id or name of the Alerter to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename the Build at id to the given name. + * Response: [Update]. + */ +export interface RenameBuild { + /** The id or name of the Build to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename the Builder at id to the given name. + * Response: [Update]. + */ +export interface RenameBuilder { + /** The id or name of the Builder to rename. */ + id: string; + /** The new name. */ + name: string; +} /** * Rename the deployment at id to the given name. Response: [Update]. * @@ -5652,9 +5704,52 @@ export interface RenameDeployment { /** The new name. */ name: string; } -/** Rename the server at id to the given name. Response: [Update]. */ +/** + * Rename the Procedure at id to the given name. + * Response: [Update]. + */ +export interface RenameProcedure { + /** The id or name of the Procedure to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename the Repo at id to the given name. + * Response: [Update]. + */ +export interface RenameRepo { + /** The id or name of the Repo to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename the ResourceSync at id to the given name. + * Response: [Update]. + */ +export interface RenameResourceSync { + /** The id or name of the ResourceSync to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename an Server to the given name. + * Response: [Update]. + */ export interface RenameServer { - /** The id of the server to rename. */ + /** The id or name of the Server to rename. */ + id: string; + /** The new name. */ + name: string; +} +/** + * Rename the ServerTemplate at id to the given name. + * Response: [Update]. + */ +export interface RenameServerTemplate { + /** The id or name of the ServerTemplate to rename. */ id: string; /** The new name. */ name: string; @@ -6191,7 +6286,7 @@ export interface UpdateResourceSync { * field changes occur from out of date local state. */ export interface UpdateServer { - /** The id of the server to update. */ + /** The id or name of the server to update. */ id: string; /** The partial config update to apply. */ config: _PartialServerConfig; @@ -6969,6 +7064,9 @@ export type WriteRequest = { } | { type: "UpdateBuild"; params: UpdateBuild; +} | { + type: "RenameBuild"; + params: RenameBuild; } | { type: "RefreshBuildCache"; params: RefreshBuildCache; @@ -6990,6 +7088,9 @@ export type WriteRequest = { } | { type: "UpdateBuilder"; params: UpdateBuilder; +} | { + type: "RenameBuilder"; + params: RenameBuilder; } | { type: "CreateServerTemplate"; params: CreateServerTemplate; @@ -7002,6 +7103,9 @@ export type WriteRequest = { } | { type: "UpdateServerTemplate"; params: UpdateServerTemplate; +} | { + type: "RenameServerTemplate"; + params: RenameServerTemplate; } | { type: "CreateRepo"; params: CreateRepo; @@ -7014,6 +7118,9 @@ export type WriteRequest = { } | { type: "UpdateRepo"; params: UpdateRepo; +} | { + type: "RenameRepo"; + params: RenameRepo; } | { type: "RefreshRepoCache"; params: RefreshRepoCache; @@ -7035,6 +7142,9 @@ export type WriteRequest = { } | { type: "UpdateAlerter"; params: UpdateAlerter; +} | { + type: "RenameAlerter"; + params: RenameAlerter; } | { type: "CreateProcedure"; params: CreateProcedure; @@ -7047,6 +7157,9 @@ export type WriteRequest = { } | { type: "UpdateProcedure"; params: UpdateProcedure; +} | { + type: "RenameProcedure"; + params: RenameProcedure; } | { type: "CreateAction"; params: CreateAction; @@ -7059,6 +7172,9 @@ export type WriteRequest = { } | { type: "UpdateAction"; params: UpdateAction; +} | { + type: "RenameAction"; + params: RenameAction; } | { type: "CreateResourceSync"; params: CreateResourceSync; @@ -7071,6 +7187,9 @@ export type WriteRequest = { } | { type: "UpdateResourceSync"; params: UpdateResourceSync; +} | { + type: "RenameResourceSync"; + params: RenameResourceSync; } | { type: "WriteSyncFileContents"; params: WriteSyncFileContents; diff --git a/frontend/public/client/types.js b/frontend/public/client/types.js index 88cc4fefa..ea96da7eb 100644 --- a/frontend/public/client/types.js +++ b/frontend/public/client/types.js @@ -159,6 +159,7 @@ export var Operation; Operation["StopStackService"] = "StopStackService"; Operation["CreateDeployment"] = "CreateDeployment"; Operation["UpdateDeployment"] = "UpdateDeployment"; + Operation["RenameDeployment"] = "RenameDeployment"; Operation["DeleteDeployment"] = "DeleteDeployment"; Operation["Deploy"] = "Deploy"; Operation["StartDeployment"] = "StartDeployment"; @@ -167,14 +168,15 @@ export var Operation; Operation["UnpauseDeployment"] = "UnpauseDeployment"; Operation["StopDeployment"] = "StopDeployment"; Operation["DestroyDeployment"] = "DestroyDeployment"; - Operation["RenameDeployment"] = "RenameDeployment"; Operation["CreateBuild"] = "CreateBuild"; Operation["UpdateBuild"] = "UpdateBuild"; + Operation["RenameBuild"] = "RenameBuild"; Operation["DeleteBuild"] = "DeleteBuild"; Operation["RunBuild"] = "RunBuild"; Operation["CancelBuild"] = "CancelBuild"; Operation["CreateRepo"] = "CreateRepo"; Operation["UpdateRepo"] = "UpdateRepo"; + Operation["RenameRepo"] = "RenameRepo"; Operation["DeleteRepo"] = "DeleteRepo"; Operation["CloneRepo"] = "CloneRepo"; Operation["PullRepo"] = "PullRepo"; @@ -182,24 +184,30 @@ export var Operation; Operation["CancelRepoBuild"] = "CancelRepoBuild"; Operation["CreateProcedure"] = "CreateProcedure"; Operation["UpdateProcedure"] = "UpdateProcedure"; + Operation["RenameProcedure"] = "RenameProcedure"; Operation["DeleteProcedure"] = "DeleteProcedure"; Operation["RunProcedure"] = "RunProcedure"; Operation["CreateAction"] = "CreateAction"; Operation["UpdateAction"] = "UpdateAction"; + Operation["RenameAction"] = "RenameAction"; Operation["DeleteAction"] = "DeleteAction"; Operation["RunAction"] = "RunAction"; Operation["CreateBuilder"] = "CreateBuilder"; Operation["UpdateBuilder"] = "UpdateBuilder"; + Operation["RenameBuilder"] = "RenameBuilder"; Operation["DeleteBuilder"] = "DeleteBuilder"; Operation["CreateAlerter"] = "CreateAlerter"; Operation["UpdateAlerter"] = "UpdateAlerter"; + Operation["RenameAlerter"] = "RenameAlerter"; Operation["DeleteAlerter"] = "DeleteAlerter"; Operation["CreateServerTemplate"] = "CreateServerTemplate"; Operation["UpdateServerTemplate"] = "UpdateServerTemplate"; + Operation["RenameServerTemplate"] = "RenameServerTemplate"; Operation["DeleteServerTemplate"] = "DeleteServerTemplate"; Operation["LaunchServer"] = "LaunchServer"; Operation["CreateResourceSync"] = "CreateResourceSync"; Operation["UpdateResourceSync"] = "UpdateResourceSync"; + Operation["RenameResourceSync"] = "RenameResourceSync"; Operation["DeleteResourceSync"] = "DeleteResourceSync"; Operation["WriteSyncContents"] = "WriteSyncContents"; Operation["CommitSync"] = "CommitSync"; diff --git a/frontend/src/components/config/index.tsx b/frontend/src/components/config/index.tsx index 75b044109..8b05865db 100644 --- a/frontend/src/components/config/index.tsx +++ b/frontend/src/components/config/index.tsx @@ -16,7 +16,7 @@ import { SelectValue, } from "@ui/select"; import { AlertTriangle, History, Settings } from "lucide-react"; -import { Fragment, ReactNode, SetStateAction } from "react"; +import { Fragment, ReactNode, SetStateAction, useMemo } from "react"; const keys = >(obj: T) => Object.keys(obj) as Array; @@ -148,13 +148,19 @@ export const Config = ({ // ); // const show = (components[_show] && _show) || component_keys[0]; - let activeCount = 0; - for (const key in components) { - if (components[key] && components[key].length) { - activeCount++; + const showSidebar = useMemo(() => { + let activeCount = 0; + for (const key in components) { + for (const component of components[key] || []) { + for (const key in component.components || {}) { + if (component.components[key]) { + activeCount++; + } + } + } } - } - const showSidebar = activeCount > 1; + return activeCount > 1; + }, [components]); const sections = keys(components).filter((section) => !!components[section]); diff --git a/frontend/src/components/config/util.tsx b/frontend/src/components/config/util.tsx index 854e5e7ec..7a1702de9 100644 --- a/frontend/src/components/config/util.tsx +++ b/frontend/src/components/config/util.tsx @@ -1,5 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { useCtrlKeyListener, useRead } from "@lib/hooks"; +import { + useCtrlKeyListener, + useInvalidate, + useRead, + useWrite, +} from "@lib/hooks"; import { Types } from "komodo_client"; import { Select, @@ -14,6 +19,7 @@ import { Switch } from "@ui/switch"; import { CheckCircle, MinusCircle, + Pen, PlusCircle, Save, Search, @@ -54,6 +60,8 @@ import { } from "@components/monaco"; import { useSettingsView } from "@pages/settings"; import { useNavigate } from "react-router-dom"; +import { useToast } from "@ui/use-toast"; +import { UsableResource } from "@types"; export const ConfigItem = ({ label, @@ -197,7 +205,7 @@ export const DoubleInput = < T extends object, K extends keyof T, L extends T[K] extends string | number | undefined ? K : never, - R extends T[K] extends string | number | undefined ? K : never + R extends T[K] extends string | number | undefined ? K : never, >({ disabled, values, @@ -518,7 +526,7 @@ export const ConfigList = ( className="flex items-center gap-2 w-[200px]" > - {props.addLabel ?? "Add " + props.label?.endsWith("s") + {(props.addLabel ?? "Add " + props.label?.endsWith("s")) ? props.label?.slice(0, -1) : props.label} @@ -665,24 +673,24 @@ function ConfirmUpdateItem({ typeof _val === "string" ? _val : Array.isArray(_val) - ? _val.length > 0 && - ["string", "number", "boolean"].includes(typeof _val[0]) - ? JSON.stringify(_val) - : JSON.stringify(_val, null, 2) - : JSON.stringify(_val, null, 2); + ? _val.length > 0 && + ["string", "number", "boolean"].includes(typeof _val[0]) + ? JSON.stringify(_val) + : JSON.stringify(_val, null, 2) + : JSON.stringify(_val, null, 2); const prev_val = typeof previous[_key] === "string" ? previous[_key] : _key === "environment" || - _key === "build_args" || - _key === "secret_args" - ? env_to_text(previous[_key] as any) ?? "" // For backward compat with 1.14 - : Array.isArray(previous[_key]) - ? previous[_key].length > 0 && - ["string", "number", "boolean"].includes(typeof previous[_key][0]) - ? JSON.stringify(previous[_key]) - : JSON.stringify(previous[_key], null, 2) - : JSON.stringify(previous[_key], null, 2); + _key === "build_args" || + _key === "secret_args" + ? (env_to_text(previous[_key] as any) ?? "") // For backward compat with 1.14 + : Array.isArray(previous[_key]) + ? previous[_key].length > 0 && + ["string", "number", "boolean"].includes(typeof previous[_key][0]) + ? JSON.stringify(previous[_key]) + : JSON.stringify(previous[_key], null, 2) + : JSON.stringify(previous[_key], null, 2); const showDiff = val?.includes("\n") || prev_val?.includes("\n") || @@ -711,8 +719,8 @@ function ConfirmUpdateItem({ ) ? "key_value" : _key === "file_contents" - ? file_contents_language - : "json") + ? file_contents_language + : "json") } /> ) : ( @@ -1126,3 +1134,52 @@ export const PermissionLevelSelector = ({ ); }; + +export const RenameResource = ({ + type, + id, +}: { + type: UsableResource; + id: string; +}) => { + const invalidate = useInvalidate(); + + const { toast } = useToast(); + const { mutate, isPending } = useWrite(`Rename${type}`, { + onSuccess: () => { + invalidate([`List${type}s`]); + toast({ title: `${type} Renamed` }); + set(""); + }, + }); + + const [name, set] = useState(""); + + return ( +
+
+ Rename{" "} + {type === "ServerTemplate" + ? "Template" + : type === "ResourceSync" + ? "Sync" + : type} +
+
+ set(e.target.value)} + className="w-96" + placeholder="Enter new name" + /> + } + disabled={!name || isPending} + loading={isPending} + onClick={() => mutate({ id, name })} + /> +
+
+ ); +}; diff --git a/frontend/src/components/resources/action/index.tsx b/frontend/src/components/resources/action/index.tsx index 9bf489300..c1e714949 100644 --- a/frontend/src/components/resources/action/index.tsx +++ b/frontend/src/components/resources/action/index.tsx @@ -17,6 +17,7 @@ import { cn } from "@lib/utils"; import { Types } from "komodo_client"; import { DashboardPieChart } from "@pages/home/dashboard"; import { ActionInfo } from "./info"; +import { RenameResource } from "@components/config/util"; const useAction = (id?: string) => useRead("ListActions", {}).data?.find((d) => d.id === id); @@ -113,7 +114,12 @@ export const ActionComponents: RequiredResourceComponents = { Config: ConfigInfo, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const action = useAction(id); diff --git a/frontend/src/components/resources/alerter/index.tsx b/frontend/src/components/resources/alerter/index.tsx index bae4063cb..4e330f23c 100644 --- a/frontend/src/components/resources/alerter/index.tsx +++ b/frontend/src/components/resources/alerter/index.tsx @@ -8,6 +8,7 @@ import { DeleteResource, NewResource } from "../common"; import { AlerterTable } from "./table"; import { Types } from "komodo_client"; import { ResourcePageHeader } from "@components/util"; +import { RenameResource } from "@components/config/util"; const useAlerter = (id?: string) => useRead("ListAlerters", {}).data?.find((d) => d.id === id); @@ -67,7 +68,12 @@ export const AlerterComponents: RequiredResourceComponents = { Config: AlerterConfig, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const alerter = useAlerter(id); diff --git a/frontend/src/components/resources/build/index.tsx b/frontend/src/components/resources/build/index.tsx index 5a5279fc8..d6bcc4eed 100644 --- a/frontend/src/components/resources/build/index.tsx +++ b/frontend/src/components/resources/build/index.tsx @@ -25,6 +25,7 @@ import { Badge } from "@ui/badge"; import { useToast } from "@ui/use-toast"; import { Button } from "@ui/button"; import { useBuilder } from "../builder"; +import { RenameResource } from "@components/config/util"; export const useBuild = (id?: string) => useRead("ListBuilds", {}, { refetchInterval: 10_000 }).data?.find( @@ -263,7 +264,12 @@ export const BuildComponents: RequiredResourceComponents = { Config: ConfigOrDeployments, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const build = useBuild(id); diff --git a/frontend/src/components/resources/builder/index.tsx b/frontend/src/components/resources/builder/index.tsx index 33387a50e..67c50efba 100644 --- a/frontend/src/components/resources/builder/index.tsx +++ b/frontend/src/components/resources/builder/index.tsx @@ -19,6 +19,7 @@ import { BuilderConfig } from "./config"; import { DeleteResource, ResourceLink } from "../common"; import { BuilderTable } from "./table"; import { ResourcePageHeader } from "@components/util"; +import { RenameResource } from "@components/config/util"; export const useBuilder = (id?: string) => useRead("ListBuilders", {}, { refetchInterval: 10_000 }).data?.find( @@ -142,7 +143,12 @@ export const BuilderComponents: RequiredResourceComponents = { Config: BuilderConfig, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const builder = useBuilder(id); diff --git a/frontend/src/components/resources/deployment/actions.tsx b/frontend/src/components/resources/deployment/actions.tsx index 7c78b9880..6dce2b8cd 100644 --- a/frontend/src/components/resources/deployment/actions.tsx +++ b/frontend/src/components/resources/deployment/actions.tsx @@ -1,16 +1,6 @@ import { ActionWithDialog, ConfirmButton } from "@components/util"; -import { - Play, - Trash, - Pause, - Rocket, - Pen, - RefreshCcw, - Square, -} from "lucide-react"; -import { useExecute, useInvalidate, useRead, useWrite } from "@lib/hooks"; -import { Input } from "@ui/input"; -import { useToast } from "@ui/use-toast"; +import { Play, Trash, Pause, Rocket, RefreshCcw, Square } from "lucide-react"; +import { useExecute, useRead } from "@lib/hooks"; import { useEffect, useState } from "react"; import { Types } from "komodo_client"; import { @@ -58,7 +48,7 @@ export const DeployDeployment = ({ id }: DeploymentId) => { const term_signal_labels = deployed && parse_key_value(deployment.config?.term_signal_labels ?? "").map( - (s) => ({ signal: s.key, label: s.value } as Types.TerminationSignalLabel) + (s) => ({ signal: s.key, label: s.value }) as Types.TerminationSignalLabel ); if (deployed) { @@ -124,7 +114,7 @@ export const DestroyDeployment = ({ id }: DeploymentId) => { const term_signal_labels = parse_key_value( deployment.config?.term_signal_labels ?? "" ).map( - (s) => ({ signal: s.key, label: s.value } as Types.TerminationSignalLabel) + (s) => ({ signal: s.key, label: s.value }) as Types.TerminationSignalLabel ); return ( @@ -232,7 +222,7 @@ const StopDeployment = ({ id }: DeploymentId) => { const term_signal_labels = parse_key_value( deployment.config?.term_signal_labels ?? "" ).map( - (s) => ({ signal: s.key, label: s.value } as Types.TerminationSignalLabel) + (s) => ({ signal: s.key, label: s.value }) as Types.TerminationSignalLabel ); return ( @@ -335,36 +325,3 @@ export const PauseUnpauseDeployment = ({ id }: DeploymentId) => { ); } }; - -export const RenameDeployment = ({ id }: { id: string }) => { - const invalidate = useInvalidate(); - const [name, set] = useState(""); - const { toast } = useToast(); - const { mutate, isPending } = useWrite("RenameDeployment", { - onSuccess: () => { - invalidate(["ListDeployments"]); - toast({ title: "Deployment renamed" }); - set(""); - }, - }); - return ( -
-
Rename Deployment
-
- set(e.target.value)} - className="w-96" - placeholder="Enter new name" - /> - } - loading={isPending} - disabled={!name || isPending} - onClick={() => mutate({ id, name })} - /> -
-
- ); -}; diff --git a/frontend/src/components/resources/deployment/index.tsx b/frontend/src/components/resources/deployment/index.tsx index 8b710c772..5d4d06c7b 100644 --- a/frontend/src/components/resources/deployment/index.tsx +++ b/frontend/src/components/resources/deployment/index.tsx @@ -8,7 +8,6 @@ import { DeployDeployment, StartStopDeployment, DestroyDeployment, - RenameDeployment, RestartDeployment, PauseUnpauseDeployment, } from "./actions"; @@ -24,6 +23,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs"; import { DeploymentConfig } from "./config"; import { DashboardPieChart } from "@pages/home/dashboard"; import { ResourcePageHeader, StatusBadge } from "@components/util"; +import { RenameResource } from "@components/config/util"; // const configOrLog = atomWithStorage("config-or-log-v1", "Config"); @@ -33,7 +33,8 @@ export const useDeployment = (id?: string) => ); export const useFullDeployment = (id: string) => - useRead("GetDeployment", { deployment: id }, { refetchInterval: 10_000 }).data; + useRead("GetDeployment", { deployment: id }, { refetchInterval: 10_000 }) + .data; const ConfigOrLog = ({ id }: { id: string }) => { // const [view, setView] = useAtom(configOrLog); @@ -149,8 +150,8 @@ export const DeploymentComponents: RequiredResourceComponents = { const server_id = _server_id ? _server_id : servers && servers.length === 1 - ? servers[0].id - : undefined; + ? servers[0].id + : undefined; return ( ( <> - + ), diff --git a/frontend/src/components/resources/procedure/index.tsx b/frontend/src/components/resources/procedure/index.tsx index 287f7570b..401a9bc20 100644 --- a/frontend/src/components/resources/procedure/index.tsx +++ b/frontend/src/components/resources/procedure/index.tsx @@ -16,6 +16,7 @@ import { import { cn } from "@lib/utils"; import { Types } from "komodo_client"; import { DashboardPieChart } from "@pages/home/dashboard"; +import { RenameResource } from "@components/config/util"; const useProcedure = (id?: string) => useRead("ListProcedures", {}).data?.find((d) => d.id === id); @@ -75,7 +76,7 @@ export const ProcedureComponents: RequiredResourceComponents = { ); }, - + Status: {}, Info: { @@ -109,7 +110,12 @@ export const ProcedureComponents: RequiredResourceComponents = { Config: ProcedureConfig, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const procedure = useProcedure(id); diff --git a/frontend/src/components/resources/repo/index.tsx b/frontend/src/components/resources/repo/index.tsx index 9bdb779c0..7989f76c3 100644 --- a/frontend/src/components/resources/repo/index.tsx +++ b/frontend/src/components/resources/repo/index.tsx @@ -1,12 +1,7 @@ import { useInvalidate, useRead, useWrite } from "@lib/hooks"; import { RequiredResourceComponents } from "@types"; import { Card } from "@ui/card"; -import { - FolderGit, - GitBranch, - Loader2, - RefreshCcw, -} from "lucide-react"; +import { FolderGit, GitBranch, Loader2, RefreshCcw } from "lucide-react"; import { RepoConfig } from "./config"; import { BuildRepo, CloneRepo, PullRepo } from "./actions"; import { DeleteResource, NewResource, ResourceLink } from "../common"; @@ -25,6 +20,7 @@ import { Badge } from "@ui/badge"; import { useToast } from "@ui/use-toast"; import { Button } from "@ui/button"; import { useBuilder } from "../builder"; +import { RenameResource } from "@components/config/util"; export const useRepo = (id?: string) => useRead("ListRepos", {}, { refetchInterval: 10_000 }).data?.find( @@ -241,7 +237,12 @@ export const RepoComponents: RequiredResourceComponents = { Config: RepoConfig, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const repo = useRepo(id); diff --git a/frontend/src/components/resources/resource-sync/index.tsx b/frontend/src/components/resources/resource-sync/index.tsx index 5ba70ed84..b74c234be 100644 --- a/frontend/src/components/resources/resource-sync/index.tsx +++ b/frontend/src/components/resources/resource-sync/index.tsx @@ -21,6 +21,7 @@ import { ResourceSyncConfig } from "./config"; import { ResourceSyncInfo } from "./info"; import { ResourceSyncPending } from "./pending"; import { Badge } from "@ui/badge"; +import { RenameResource } from "@components/config/util"; export const useResourceSync = (id?: string) => useRead("ListResourceSyncs", {}, { refetchInterval: 10_000 }).data?.find( @@ -233,7 +234,12 @@ export const ResourceSyncComponents: RequiredResourceComponents = { Config: ConfigInfoPending, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const sync = useResourceSync(id); diff --git a/frontend/src/components/resources/server-template/index.tsx b/frontend/src/components/resources/server-template/index.tsx index ce42de309..d49b6ddae 100644 --- a/frontend/src/components/resources/server-template/index.tsx +++ b/frontend/src/components/resources/server-template/index.tsx @@ -20,6 +20,7 @@ import { import { ServerTemplateTable } from "./table"; import { LaunchServer } from "./actions"; import { ResourcePageHeader } from "@components/util"; +import { RenameResource } from "@components/config/util"; export const useServerTemplate = (id?: string) => useRead("ListServerTemplates", {}).data?.find((d) => d.id === id); @@ -137,7 +138,12 @@ export const ServerTemplateComponents: RequiredResourceComponents = { Config: ServerTemplateConfig, - DangerZone: ({ id }) => , + DangerZone: ({ id }) => ( + <> + + + + ), ResourcePageHeader: ({ id }) => { const template = useServerTemplate(id); diff --git a/frontend/src/components/resources/server/actions.tsx b/frontend/src/components/resources/server/actions.tsx index c6c8e075b..2b998e281 100644 --- a/frontend/src/components/resources/server/actions.tsx +++ b/frontend/src/components/resources/server/actions.tsx @@ -1,49 +1,10 @@ import { ActionWithDialog, ConfirmButton } from "@components/util"; -import { useExecute, useInvalidate, useRead, useWrite } from "@lib/hooks"; -import { Input } from "@ui/input"; -import { useToast } from "@ui/use-toast"; -import { Pen, Scissors } from "lucide-react"; -import { useState } from "react"; +import { useExecute, useRead } from "@lib/hooks"; +import { Scissors } from "lucide-react"; import { useServer } from "."; import { has_minimum_permissions } from "@lib/utils"; import { Types } from "komodo_client"; -export const RenameServer = ({ id }: { id: string }) => { - const invalidate = useInvalidate(); - - const { toast } = useToast(); - const { mutate, isPending } = useWrite("RenameServer", { - onSuccess: () => { - invalidate(["ListServers"]); - toast({ title: "Server Renamed" }); - set(""); - }, - }); - - const [name, set] = useState(""); - - return ( -
-
Rename Server
-
- set(e.target.value)} - className="w-96" - placeholder="Enter new name" - /> - } - disabled={!name || isPending} - loading={isPending} - onClick={() => mutate({ id, name })} - /> -
-
- ); -}; - export const Prune = ({ server_id, type, @@ -73,16 +34,16 @@ export const Prune = ({ type === "Containers" ? "pruning_containers" : type === "Images" - ? "pruning_images" - : type === "Networks" - ? "pruning_networks" - : type === "Volumes" - ? "pruning_volumes" - : type === "Buildx" - ? "pruning_buildx" - : type === "System" - ? "pruning_system" - : ""; + ? "pruning_images" + : type === "Networks" + ? "pruning_networks" + : type === "Volumes" + ? "pruning_volumes" + : type === "Buildx" + ? "pruning_buildx" + : type === "System" + ? "pruning_system" + : ""; const pending = isPending || action_state?.[pruningKey]; diff --git a/frontend/src/components/resources/server/index.tsx b/frontend/src/components/resources/server/index.tsx index ead0c8295..386d3c0a9 100644 --- a/frontend/src/components/resources/server/index.tsx +++ b/frontend/src/components/resources/server/index.tsx @@ -14,7 +14,7 @@ import { Square, } from "lucide-react"; import { Section } from "@components/layouts"; -import { Prune, RenameServer } from "./actions"; +import { Prune } from "./actions"; import { server_state_intention, stroke_color_class_by_intention, @@ -36,6 +36,7 @@ import { StackTable } from "../stack/table"; import { ResourceComponents } from ".."; import { ServerInfo } from "./info"; import { ServerStats } from "./stats"; +import { RenameResource } from "@components/config/util"; export const useServer = (id?: string) => useRead("ListServers", {}, { refetchInterval: 10_000 }).data?.find( @@ -438,7 +439,7 @@ export const ServerComponents: RequiredResourceComponents = { DangerZone: ({ id }) => ( <> - + ), diff --git a/frontend/src/components/resources/stack/actions.tsx b/frontend/src/components/resources/stack/actions.tsx index 52ebe518e..166df4de4 100644 --- a/frontend/src/components/resources/stack/actions.tsx +++ b/frontend/src/components/resources/stack/actions.tsx @@ -1,19 +1,8 @@ import { ActionWithDialog, ConfirmButton } from "@components/util"; -import { useExecute, useInvalidate, useRead, useWrite } from "@lib/hooks"; -import { - Pause, - Pen, - Play, - RefreshCcw, - Rocket, - Square, - Trash, -} from "lucide-react"; +import { useExecute, useRead } from "@lib/hooks"; +import { Pause, Play, RefreshCcw, Rocket, Square, Trash } from "lucide-react"; import { useStack } from "."; import { Types } from "komodo_client"; -import { useToast } from "@ui/use-toast"; -import { useState } from "react"; -import { Input } from "@ui/input"; export const DeployStack = ({ id }: { id: string }) => { const stack = useStack(id); @@ -170,14 +159,14 @@ export const StartStopStack = ({ } const showStart = service - ? (container_state && + ? ((container_state && container_state !== Types.ContainerStateStatusEnum.Running) ?? - false + false) : state !== Types.StackState.Running; const showStop = service - ? (container_state && + ? ((container_state && container_state !== Types.ContainerStateStatusEnum.Exited) ?? - false + false) : state !== Types.StackState.Stopped; return ( @@ -262,33 +251,3 @@ export const PauseUnpauseStack = ({ ); } }; - -export const RenameStack = ({ id }: { id: string }) => { - const invalidate = useInvalidate(); - const [name, set] = useState(""); - const { toast } = useToast(); - const { mutate, isPending } = useWrite("RenameStack", { - onSuccess: () => { - invalidate(["ListStacks"]); - toast({ title: "Stack renamed" }); - set(""); - }, - }); - return ( -
- set(e.target.value)} - className="w-96" - placeholder="Enter new name" - /> - } - loading={isPending} - disabled={!name || isPending} - onClick={() => mutate({ id, name })} - /> -
- ); -}; diff --git a/frontend/src/components/resources/stack/index.tsx b/frontend/src/components/resources/stack/index.tsx index 345fb9d52..ae8f9808f 100644 --- a/frontend/src/components/resources/stack/index.tsx +++ b/frontend/src/components/resources/stack/index.tsx @@ -24,7 +24,6 @@ import { DeployStack, DestroyStack, PauseUnpauseStack, - RenameStack, RestartStack, StartStopStack, } from "./actions"; @@ -37,6 +36,7 @@ import { StackServices } from "./services"; import { DashboardPieChart } from "@pages/home/dashboard"; import { ResourcePageHeader, StatusBadge } from "@components/util"; import { StackConfig } from "./config"; +import { RenameResource } from "@components/config/util"; export const useStack = (id?: string) => useRead("ListStacks", {}, { refetchInterval: 10_000 }).data?.find( @@ -156,8 +156,8 @@ export const StackComponents: RequiredResourceComponents = { const server_id = _server_id ? _server_id : servers && servers.length === 1 - ? servers[0].id - : undefined; + ? servers[0].id + : undefined; return ; }, @@ -442,7 +442,7 @@ export const StackComponents: RequiredResourceComponents = { DangerZone: ({ id }) => ( <> - + ), diff --git a/lib/command/src/lib.rs b/lib/command/src/lib.rs index 558c314cc..2cbf3700f 100644 --- a/lib/command/src/lib.rs +++ b/lib/command/src/lib.rs @@ -6,10 +6,10 @@ use komodo_client::{ }; use run_command::{async_run_command, CommandOutput}; -/// Parses commands out of multiline string -/// and chains them together with '&&' -/// -/// Supports full line and end of line comments. See [parse_multiline_command]. +/// If `parse_multiline: true`, parses commands out of multiline string +/// and chains them together with '&&'. +/// Supports full line and end of line comments. +/// See [parse_multiline_command]. pub async fn run_komodo_command( stage: &str, path: impl Into>, diff --git a/lib/logger/src/lib.rs b/lib/logger/src/lib.rs index 0b9c55083..48cbd8b27 100644 --- a/lib/logger/src/lib.rs +++ b/lib/logger/src/lib.rs @@ -14,7 +14,9 @@ pub fn init(config: &LogConfig) -> anyhow::Result<()> { let registry = Registry::default().with(LevelFilter::from(log_level)); - match (config.stdio, !config.otlp_endpoint.is_empty()) { + let use_otel = !config.otlp_endpoint.is_empty(); + + match (config.stdio, use_otel) { (StdioLogMode::Standard, true) => { let tracer = otel::tracer( &config.otlp_endpoint, diff --git a/roadmap.md b/roadmap.md index 56dbbd496..f1e7d9ab8 100644 --- a/roadmap.md +++ b/roadmap.md @@ -11,7 +11,8 @@ If you have an idea for Komodo, feel free to open an issue beginning with the `[ - **v1.14**: Manage docker networks, images, volumes in the UI ✅ - **v1.15**: Support generic OIDC providers (including self-hosted) ✅ - **v1.16**: "Action" resource: Run requests on the Komodo API using snippets of typescript. -- **v1.17**: Support "Swarm" resource - Manage docker swarms, attach Deployments / Stacks to "Swarm". -- **v1.18+**: Support "Cluster" resource - Manage Kubernetes cluster, can attach deployments to "Cluster" (in addition to existing "Server") +- **v1.17**: Procedure Schedules: Run procedures at scheduled times, like CRON job. +- **v1.18**: Support "Swarm" resource - Manage docker swarms, attach Deployments / Stacks to "Swarm". +- **v1.19+**: Support "Cluster" resource - Manage Kubernetes cluster, can attach deployments to "Cluster" (in addition to existing "Server") **Note. The specific versions associated with these features are not final.** \ No newline at end of file