Compare commits

..
7 Commits
Author SHA1 Message Date
mbecker20 3b72dc65cc remove "Overviews" label from sidebar 2024-10-22 02:27:22 -04:00
mbecker20 05f38d02be bump version to 1.16.1 2024-10-22 02:21:16 -04:00
Maxwell BeckerandGitHub ea5506c202 1.16.1 (#143)
* ensure sync state cache is refreshed on sync create / copy

* clean up resources post_create

* show sidebar if element length > 1

* update `run_komodo_command` command

* rename all resources

* refresh repo cache after clone / pull

* improve rename repo log
2024-10-21 23:19:40 -07:00
mbecker20 64b0a5c9d2 delete unrelated caddy compose 2024-10-21 00:30:54 -04:00
mbecker20 93cc6a3a6e Add running Action to dashboard "Active" 2024-10-21 00:21:17 -04:00
mbecker20 7ae69cf33b ignore top level return linting 2024-10-20 05:10:28 -04:00
mbecker20 404e00cc64 move action info inline 2024-10-20 04:43:29 -04:00
75 changed files with 1193 additions and 502 deletions
Generated
+12 -12
View File
@@ -41,7 +41,7 @@ dependencies = [
[[package]]
name = "alerter"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"axum",
@@ -943,7 +943,7 @@ dependencies = [
[[package]]
name = "command"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"komodo_client",
"run_command",
@@ -1355,7 +1355,7 @@ dependencies = [
[[package]]
name = "environment_file"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"thiserror",
]
@@ -1439,7 +1439,7 @@ dependencies = [
[[package]]
name = "formatting"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"serror",
]
@@ -1571,7 +1571,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "git"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"command",
@@ -2191,7 +2191,7 @@ dependencies = [
[[package]]
name = "komodo_cli"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"clap",
@@ -2207,7 +2207,7 @@ dependencies = [
[[package]]
name = "komodo_client"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"async_timing_util",
@@ -2238,7 +2238,7 @@ dependencies = [
[[package]]
name = "komodo_core"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"async_timing_util",
@@ -2296,7 +2296,7 @@ dependencies = [
[[package]]
name = "komodo_periphery"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"async_timing_util",
@@ -2383,7 +2383,7 @@ dependencies = [
[[package]]
name = "logger"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"komodo_client",
@@ -3089,7 +3089,7 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "periphery_client"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"komodo_client",
@@ -4863,7 +4863,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "update_logger"
version = "1.16.0"
version = "1.16.1"
dependencies = [
"anyhow",
"komodo_client",
+1 -1
View File
@@ -9,7 +9,7 @@ members = [
]
[workspace.package]
version = "1.16.0"
version = "1.16.1"
edition = "2021"
authors = ["mbecker20 <becker.maxh@gmail.com>"]
license = "GPL-3.0-or-later"
+23 -1
View File
@@ -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<CloneRepo, (User, Update)> 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<PullRepo, (User, Update)> 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
}
}
+13 -1
View File
@@ -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<UpdateAction, User> for State {
}
}
impl Resolve<RenameAction, User> for State {
#[instrument(name = "RenameAction", skip(self, user))]
async fn resolve(
&self,
RenameAction { id, name }: RenameAction,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<Action>(&id, &name, &user).await
}
}
impl Resolve<DeleteAction, User> for State {
#[instrument(name = "DeleteAction", skip(self, user))]
async fn resolve(
+14 -4
View File
@@ -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<UpdateAlerter, User> for State {
resource::update::<Alerter>(&id, config, &user).await
}
}
impl Resolve<RenameAlerter, User> for State {
#[instrument(name = "RenameAlerter", skip(self, user))]
async fn resolve(
&self,
RenameAlerter { id, name }: RenameAlerter,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<Alerter>(&id, &name, &user).await
}
}
+12
View File
@@ -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<UpdateBuild, User> for State {
}
}
impl Resolve<RenameBuild, User> for State {
#[instrument(name = "RenameBuild", skip(self, user))]
async fn resolve(
&self,
RenameBuild { id, name }: RenameBuild,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<Build>(&id, &name, &user).await
}
}
impl Resolve<RefreshBuildCache, User> for State {
#[instrument(
name = "RefreshBuildCache",
+13 -1
View File
@@ -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<UpdateBuilder, User> for State {
resource::update::<Builder>(&id, config, &user).await
}
}
impl Resolve<RenameBuilder, User> for State {
#[instrument(name = "RenameBuilder", skip(self, user))]
async fn resolve(
&self,
RenameBuilder { id, name }: RenameBuilder,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<Builder>(&id, &name, &user).await
}
}
+6 -7
View File
@@ -108,7 +108,7 @@ impl Resolve<RenameDeployment, User> 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<RenameDeployment, User> 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<RenameDeployment, User> 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)
}
+8
View File
@@ -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),
+13 -1
View File
@@ -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<UpdateProcedure, User> for State {
}
}
impl Resolve<RenameProcedure, User> for State {
#[instrument(name = "RenameProcedure", skip(self, user))]
async fn resolve(
&self,
RenameProcedure { id, name }: RenameProcedure,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<Procedure>(&id, &name, &user).await
}
}
impl Resolve<DeleteProcedure, User> for State {
#[instrument(name = "DeleteProcedure", skip(self, user))]
async fn resolve(
+88 -4
View File
@@ -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<CreateRepo, User> for State {
@@ -75,6 +84,81 @@ impl Resolve<UpdateRepo, User> for State {
}
}
impl Resolve<RenameRepo, User> for State {
#[instrument(name = "RenameRepo", skip(self, user))]
async fn resolve(
&self,
RenameRepo { id, name }: RenameRepo,
user: User,
) -> anyhow::Result<Update> {
let repo = resource::get_check_permissions::<Repo>(
&id,
&user,
PermissionLevel::Write,
)
.await?;
if repo.config.server_id.is_empty()
|| !repo.config.path.is_empty()
{
return resource::rename::<Repo>(&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::<Server>(&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<RefreshRepoCache, User> for State {
#[instrument(
name = "RefreshRepoCache",
+2 -23
View File
@@ -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<CreateServer, User> for State {
@@ -64,25 +61,7 @@ impl Resolve<RenameServer, User> for State {
RenameServer { id, name }: RenameServer,
user: User,
) -> anyhow::Result<Update> {
let server = resource::get_check_permissions::<Server>(
&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::<Server>(&id, &name, &user).await
}
}
+13 -2
View File
@@ -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<UpdateServerTemplate, User> for State {
resource::update::<ServerTemplate>(&id, config, &user).await
}
}
impl Resolve<RenameServerTemplate, User> for State {
#[instrument(name = "RenameServerTemplate", skip(self, user))]
async fn resolve(
&self,
RenameServerTemplate { id, name }: RenameServerTemplate,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<ServerTemplate>(&id, &name, &user).await
}
}
+2 -35
View File
@@ -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<RenameStack, User> for State {
RenameStack { id, name }: RenameStack,
user: User,
) -> anyhow::Result<Update> {
let stack = resource::get_check_permissions::<Stack>(
&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::<Stack>(&id, &name, &user).await
}
}
+33 -2
View File
@@ -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<UpdateResourceSync, User> for State {
}
}
impl Resolve<RenameResourceSync, User> for State {
#[instrument(name = "RenameResourceSync", skip(self, user))]
async fn resolve(
&self,
RenameResourceSync { id, name }: RenameResourceSync,
user: User,
) -> anyhow::Result<Update> {
resource::rename::<ResourceSync>(&id, &name, &user).await
}
}
impl Resolve<WriteSyncFileContents, User> for State {
async fn resolve(
&self,
+11 -6
View File
@@ -31,8 +31,8 @@ impl super::KomodoResource for Action {
ResourceTargetVariant::Action
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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
+8 -2
View File
@@ -25,8 +25,8 @@ impl super::KomodoResource for Alerter {
ResourceTargetVariant::Alerter
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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 {
+11 -6
View File
@@ -38,8 +38,8 @@ impl super::KomodoResource for Build {
ResourceTargetVariant::Build
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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
+8 -2
View File
@@ -31,8 +31,8 @@ impl super::KomodoResource for Builder {
ResourceTargetVariant::Builder
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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 {
+24 -14
View File
@@ -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<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&db_client().deployments
}
@@ -132,11 +131,21 @@ impl super::KomodoResource for Deployment {
created: &Resource<Self::Config, Self::Info>,
_update: &mut Update,
) -> anyhow::Result<()> {
if !created.config.server_id.is_empty() {
let server =
resource::get::<Server>(&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::<Server>(&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::<Server>(&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
+69 -19
View File
@@ -110,8 +110,7 @@ pub trait KomodoResource {
fn resource_type() -> ResourceTargetVariant;
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>>;
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>;
async fn to_list_item(
resource: Resource<Self::Config, Self::Info>,
@@ -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<T: KomodoResource>(
id_or_name: &str,
) -> anyhow::Result<Resource<T::Config, T::Info>> {
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<T: KomodoResource>(
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<T: KomodoResource>(
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<T: KomodoResource>(
id_to_tags: &HashMap<String, Tag>,
match_tags: &[String],
) -> anyhow::Result<IdResourceMap<T>> {
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<T: KomodoResource>(
};
let resource_id = T::coll()
.await
.insert_one(&resource)
.await
.with_context(|| {
@@ -644,14 +647,9 @@ pub async fn update<T: KomodoResource>(
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::<T>(id),
@@ -707,7 +705,6 @@ pub async fn update_description<T: KomodoResource>(
)
.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<T: KomodoResource>(
.flatten()
.collect::<Vec<_>>();
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<T: KomodoResource>(
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<T: KomodoResource>(
id_or_name: &str,
name: &str,
user: &User,
) -> anyhow::Result<Update> {
let resource = get_check_permissions::<T>(
id_or_name,
user,
PermissionLevel::Write,
)
.await?;
let mut update = make_update(
resource_target::<T>(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<T: KomodoResource>(
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())
+11 -6
View File
@@ -45,8 +45,8 @@ impl super::KomodoResource for Procedure {
ResourceTargetVariant::Procedure
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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
+14 -3
View File
@@ -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<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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
{
+8 -2
View File
@@ -30,8 +30,8 @@ impl super::KomodoResource for Server {
ResourceTargetVariant::Server
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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 {
+8 -2
View File
@@ -29,8 +29,8 @@ impl super::KomodoResource for ServerTemplate {
ResourceTargetVariant::ServerTemplate
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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 {
+9 -3
View File
@@ -44,8 +44,8 @@ impl super::KomodoResource for Stack {
ResourceTargetVariant::Stack
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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 {
+9 -2
View File
@@ -41,8 +41,8 @@ impl super::KomodoResource for ResourceSync {
ResourceTargetVariant::ResourceSync
}
async fn coll(
) -> &'static Collection<Resource<Self::Config, Self::Info>> {
fn coll() -> &'static Collection<Resource<Self::Config, Self::Info>>
{
&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 {
+1 -1
View File
@@ -32,7 +32,7 @@ pub async fn get_updates_for_execution<
id_to_tags: &HashMap<String, Tag>,
match_tags: &[String],
) -> anyhow::Result<UpdatesResult<Resource::PartialConfig>> {
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()
+1 -1
View File
@@ -22,7 +22,7 @@ pub async fn push_updates_for_view<Resource: ResourceSyncTrait>(
match_tags: &[String],
diffs: &mut Vec<ResourceDiff>,
) -> 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()
+36 -11
View File
@@ -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<PullOrCloneRepo> for State {
//
impl Resolve<RenameRepo> for State {
#[instrument(name = "RenameRepo", skip(self))]
async fn resolve(
&self,
RenameRepo {
curr_name,
new_name,
}: RenameRepo,
_: (),
) -> anyhow::Result<Log> {
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<DeleteRepo> for State {
#[instrument(name = "DeleteRepo", skip(self))]
async fn resolve(
@@ -214,14 +238,15 @@ impl Resolve<DeleteRepo> for State {
DeleteRepo { name }: DeleteRepo,
_: (),
) -> anyhow::Result<Log> {
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))
}
}
+1
View File
@@ -66,6 +66,7 @@ pub enum PeripheryRequest {
// Repo (Write)
CloneRepo(CloneRepo),
PullRepo(PullRepo),
RenameRepo(RenameRepo),
DeleteRepo(DeleteRepo),
// Build
+19
View File
@@ -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]
+22 -1
View File
@@ -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,
}
+19
View File
@@ -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(
+19 -1
View File
@@ -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,
}
@@ -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,
}
+20 -2
View File
@@ -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,
}
+19 -2
View File
@@ -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(
+9 -5
View File
@@ -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,
@@ -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,
}
+1
View File
@@ -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,
}
+18
View File
@@ -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(
+9 -1
View File
@@ -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,
+5 -3
View File
@@ -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]
+8
View File
@@ -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;
+131 -20
View File
@@ -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 }
+9
View File
@@ -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 {
-22
View File
@@ -1,22 +0,0 @@
services:
caddy:
image: caddy
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
restart: unless-stopped
command: caddy reverse-proxy --from ${KOMODO_HOST} --to core:9120
cap_add:
- NET_ADMIN
networks:
- default
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- caddy-data:/data
- caddy-config:/config
volumes:
caddy-data:
caddy-config:
+8
View File
@@ -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;
+139 -20
View File
@@ -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;
+9 -1
View File
@@ -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";
+13 -7
View File
@@ -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 = <T extends Record<string, unknown>>(obj: T) =>
Object.keys(obj) as Array<keyof T>;
@@ -148,13 +148,19 @@ export const Config = <T,>({
// );
// 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]);
+76 -19
View File
@@ -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 = <T extends { [key: string]: unknown }>(
className="flex items-center gap-2 w-[200px]"
>
<PlusCircle className="w-4 h-4" />
{props.addLabel ?? "Add " + props.label?.endsWith("s")
{(props.addLabel ?? "Add " + props.label?.endsWith("s"))
? props.label?.slice(0, -1)
: props.label}
</Button>
@@ -665,24 +673,24 @@ function ConfirmUpdateItem<T>({
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<T>({
)
? "key_value"
: _key === "file_contents"
? file_contents_language
: "json")
? file_contents_language
: "json")
}
/>
) : (
@@ -1126,3 +1134,52 @@ export const PermissionLevelSelector = ({
</Select>
);
};
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 (
<div className="flex items-center justify-between">
<div className="w-full">
Rename{" "}
{type === "ServerTemplate"
? "Template"
: type === "ResourceSync"
? "Sync"
: type}
</div>
<div className="flex gap-4 w-full justify-end">
<Input
value={name}
onChange={(e) => set(e.target.value)}
className="w-96"
placeholder="Enter new name"
/>
<ConfirmButton
title="Rename"
icon={<Pen className="w-4 h-4" />}
disabled={!name || isPending}
loading={isPending}
onClick={() => mutate({ id, name })}
/>
</div>
</div>
);
};
@@ -4,9 +4,8 @@ import { Config } from "@components/config";
import { MonacoEditor } from "@components/monaco";
import { SecretsSearch } from "@components/config/env_vars";
import { Button } from "@ui/button";
import { ReactNode } from "react";
export const ActionConfig = ({ id, titleOther }: { id: string; titleOther: ReactNode }) => {
export const ActionConfig = ({ id }: { id: string }) => {
const perms = useRead("GetPermissionLevel", {
target: { type: "Action", id },
}).data;
@@ -25,7 +24,6 @@ export const ActionConfig = ({ id, titleOther }: { id: string; titleOther: React
return (
<Config
titleOther={titleOther}
resource_id={id}
resource_type="Action"
disabled={disabled}
@@ -3,7 +3,7 @@ import {
ResourcePageHeader,
StatusBadge,
} from "@components/util";
import { useExecute, useLocalStorage, useRead } from "@lib/hooks";
import { useExecute, useRead } from "@lib/hooks";
import { RequiredResourceComponents } from "@types";
import { Clapperboard } from "lucide-react";
import { ActionConfig } from "./config";
@@ -16,8 +16,8 @@ import {
import { cn } from "@lib/utils";
import { Types } from "komodo_client";
import { DashboardPieChart } from "@pages/home/dashboard";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs";
import { ActionInfo } from "./info";
import { RenameResource } from "@components/config/util";
const useAction = (id?: string) =>
useRead("ListActions", {}).data?.find((d) => d.id === id);
@@ -29,30 +29,11 @@ const ActionIcon = ({ id, size }: { id?: string; size: number }) => {
};
const ConfigInfo = ({ id }: { id: string }) => {
const [view, setView] = useLocalStorage<"Config" | "Info">(
"action-tabs-v1",
"Config"
);
const title = (
<TabsList className="justify-start w-fit">
<TabsTrigger value="Config" className="w-[110px]">
Config
</TabsTrigger>
<TabsTrigger value="Info" className="w-[110px]">
Info
</TabsTrigger>
</TabsList>
);
return (
<Tabs value={view} onValueChange={setView as any} className="grid gap-4">
<TabsContent value="Config">
<ActionConfig id={id} titleOther={title} />
</TabsContent>
<TabsContent value="Info">
<ActionInfo id={id} titleOther={title} />
</TabsContent>
</Tabs>
<div className="flex flex-col gap-2">
<ActionConfig id={id} />
<ActionInfo id={id} />
</div>
);
};
@@ -133,7 +114,12 @@ export const ActionComponents: RequiredResourceComponents = {
Config: ConfigInfo,
DangerZone: ({ id }) => <DeleteResource type="Action" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="Action" id={id} />
<DeleteResource type="Action" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const action = useAction(id);
@@ -1,17 +1,10 @@
import { Section } from "@components/layouts";
import { ReactNode } from "react";
import { Card, CardContent, CardHeader } from "@ui/card";
import { cn, getUpdateQuery, updateLogToHtml } from "@lib/utils";
import { useRead } from "@lib/hooks";
import { text_color_class_by_intention } from "@lib/color";
export const ActionInfo = ({
id,
titleOther,
}: {
id: string;
titleOther: ReactNode;
}) => {
export const ActionInfo = ({ id }: { id: string }) => {
const update = useRead("ListUpdates", {
query: {
...getUpdateQuery({ type: "Action", id }, undefined),
@@ -28,7 +21,7 @@ export const ActionInfo = ({
const log = full_update?.logs.find((log) => log.stage === "Execute Action");
return (
<Section titleOther={titleOther}>
<Section>
{!log?.stdout && !log?.stderr && (
<Card className="flex flex-col gap-4">
<CardHeader
@@ -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 }) => <DeleteResource type="Alerter" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="Alerter" id={id} />
<DeleteResource type="Alerter" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const alerter = useAlerter(id);
@@ -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 }) => <DeleteResource type="Build" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="Build" id={id} />
<DeleteResource type="Build" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const build = useBuild(id);
@@ -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 }) => <DeleteResource type="Builder" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="Builder" id={id} />
<DeleteResource type="Builder" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const builder = useBuilder(id);
@@ -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 (
<div className="flex items-center justify-between">
<div className="w-full">Rename Deployment</div>
<div className="flex gap-4 w-full justify-end">
<Input
value={name}
onChange={(e) => set(e.target.value)}
className="w-96"
placeholder="Enter new name"
/>
<ConfirmButton
title="Rename"
icon={<Pen className="w-4 h-4" />}
loading={isPending}
disabled={!name || isPending}
onClick={() => mutate({ id, name })}
/>
</div>
</div>
);
};
@@ -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 (
<NewResource
type="Deployment"
@@ -224,7 +225,7 @@ export const DeploymentComponents: RequiredResourceComponents = {
DangerZone: ({ id }) => (
<>
<RenameDeployment id={id} />
<RenameResource type="Deployment" id={id} />
<DeleteResource type="Deployment" id={id} />
</>
),
@@ -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 = {
<StatusBadge text={state} intent={procedure_state_intention(state)} />
);
},
Status: {},
Info: {
@@ -109,7 +110,12 @@ export const ProcedureComponents: RequiredResourceComponents = {
Config: ProcedureConfig,
DangerZone: ({ id }) => <DeleteResource type="Procedure" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="Procedure" id={id} />
<DeleteResource type="Procedure" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const procedure = useProcedure(id);
@@ -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 }) => <DeleteResource type="Repo" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="Repo" id={id} />
<DeleteResource type="Repo" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const repo = useRepo(id);
@@ -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 }) => <DeleteResource type="ResourceSync" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="ResourceSync" id={id} />
<DeleteResource type="ResourceSync" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const sync = useResourceSync(id);
@@ -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 }) => <DeleteResource type="ServerTemplate" id={id} />,
DangerZone: ({ id }) => (
<>
<RenameResource type="ServerTemplate" id={id} />
<DeleteResource type="ServerTemplate" id={id} />
</>
),
ResourcePageHeader: ({ id }) => {
const template = useServerTemplate(id);
@@ -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 (
<div className="flex items-center justify-between">
<div className="w-full">Rename Server</div>
<div className="flex gap-4 w-full justify-end">
<Input
value={name}
onChange={(e) => set(e.target.value)}
className="w-96"
placeholder="Enter new name"
/>
<ConfirmButton
title="Rename"
icon={<Pen className="w-4 h-4" />}
disabled={!name || isPending}
loading={isPending}
onClick={() => mutate({ id, name })}
/>
</div>
</div>
);
};
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];
@@ -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 }) => (
<>
<RenameServer id={id} />
<RenameResource type="Server" id={id} />
<DeleteResource type="Server" id={id} />
</>
),
@@ -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 (
<div className="flex items-center justify-end gap-4 w-full">
<Input
value={name}
onChange={(e) => set(e.target.value)}
className="w-96"
placeholder="Enter new name"
/>
<ConfirmButton
title="Rename"
icon={<Pen className="w-4 h-4" />}
loading={isPending}
disabled={!name || isPending}
onClick={() => mutate({ id, name })}
/>
</div>
);
};
@@ -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 <NewResource type="Stack" server_id={server_id} />;
},
@@ -442,7 +442,7 @@ export const StackComponents: RequiredResourceComponents = {
DangerZone: ({ id }) => (
<>
<RenameStack id={id} />
<RenameResource type="Stack" id={id} />
<DeleteResource type="Stack" id={id} />
</>
),
-1
View File
@@ -20,7 +20,6 @@ export const Sidebar = () => {
return (
<div className="fixed top-0 pt-24 w-64 border-r hidden lg:block pr-8 pb-8 h-screen overflow-y-auto">
<div className="flex flex-col gap-1">
<p className="pl-4 pb-1 text-xs text-muted-foreground">Overviews</p>
<SidebarLink
label="Dashboard"
to="/"
+6 -1
View File
@@ -35,6 +35,11 @@ export async function init_monaco() {
});
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
diagnosticCodesToIgnore: [1375],
diagnosticCodesToIgnore: [
// Allows top level await
1375,
// Allows top level return
1108,
],
});
}
+19 -4
View File
@@ -5,6 +5,7 @@ import { ResourceLink, ResourceName } from "@components/resources/common";
import { TagsWithBadge } from "@components/tags";
import { StatusBadge } from "@components/util";
import {
action_state_intention,
build_state_intention,
ColorIntention,
hex_color_by_intention,
@@ -78,8 +79,8 @@ const ResourceRow = ({ type }: { type: UsableResource }) => {
type === "ServerTemplate"
? "Server Template"
: type === "ResourceSync"
? "Resource Sync"
: type;
? "Resource Sync"
: type;
return (
<div className="border rounded-md flex flex-col md:flex-row">
<Link
@@ -107,8 +108,8 @@ const ResourceRow = ({ type }: { type: UsableResource }) => {
i > 3
? "hidden 2xl:flex"
: i > 1
? "hidden sm:flex md:hidden xl:flex"
: undefined
? "hidden sm:flex md:hidden xl:flex"
: undefined
}
/>
))}
@@ -215,6 +216,10 @@ const ActiveResources = () => {
useRead("ListProcedures", {}).data?.filter(
(procedure) => procedure.info.state === Types.ProcedureState.Running
) ?? [];
const actions =
useRead("ListActions", {}).data?.filter(
(action) => action.info.state === Types.ActionState.Running
) ?? [];
const resources = [
...(builds ?? []).map((build) => ({
@@ -247,6 +252,16 @@ const ActiveResources = () => {
/>
),
})),
...(actions ?? []).map((action) => ({
type: "Action" as UsableResource,
id: action.id,
state: (
<StatusBadge
text={action.info.state}
intent={action_state_intention(action.info.state)}
/>
),
})),
];
if (resources.length === 0) return null;
+4 -4
View File
@@ -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<Option<&Path>>,
+3 -1
View File
@@ -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,
+3 -2
View File
@@ -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.**