forked from github-starred/komodo
improv the sync
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -2552,18 +2552,18 @@ checksum = "ffa94c2e5674923c67d7f3dfce1279507b191e10eb064881b46ed3e1256e5ca6"
|
||||
|
||||
[[package]]
|
||||
name = "partial_derive2"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a7b915bd76bc306b7ae6f1b5d99b0434e498ab979ecbd5df119db8a00dab972"
|
||||
checksum = "6b2bd06fda40521c285c8dfc5f6b90208d586328a295e83332b6166c2b2a4241"
|
||||
dependencies = [
|
||||
"partial_derive2_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "partial_derive2_derive"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddaac49c0e65bcb207999d2514b10b43d5f2ec2d0fb47b9d875c9a10536a294e"
|
||||
checksum = "3a506f66d52e40b2385d7b9f776fd5243d6cff16ba79147f859aa4e27d2d27cc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -30,7 +30,7 @@ derive_empty_traits = "0.1.0"
|
||||
merge_config_files = "0.1.5"
|
||||
termination_signal = "0.1.3"
|
||||
async_timing_util = "0.1.14"
|
||||
partial_derive2 = "0.4.2"
|
||||
partial_derive2 = "0.4.3"
|
||||
derive_variants = "1.0.0"
|
||||
mongo_indexed = "0.3.0"
|
||||
resolver_api = "1.1.0"
|
||||
|
||||
@@ -62,6 +62,10 @@ pub trait ResourceSync: Sized {
|
||||
resource: ResourceToml<Self::PartialConfig>,
|
||||
) -> anyhow::Result<()>;
|
||||
|
||||
/// Apply any changes to incoming toml partial config
|
||||
/// before it is diffed against existing config
|
||||
fn validate_partial_config(_config: &mut Self::PartialConfig) {}
|
||||
|
||||
/// Diffs the declared toml (partial) against the full existing config.
|
||||
/// Removes all fields from toml (partial) that haven't changed.
|
||||
fn get_diff(
|
||||
@@ -69,6 +73,10 @@ pub trait ResourceSync: Sized {
|
||||
update: Self::PartialConfig,
|
||||
) -> anyhow::Result<Self::ConfigDiff>;
|
||||
|
||||
/// Apply any changes to computed config diff
|
||||
/// before logging
|
||||
fn validate_diff(_diff: &mut Self::ConfigDiff) {}
|
||||
|
||||
/// Deletes the target resource
|
||||
async fn delete(id_or_name: String) -> anyhow::Result<()>;
|
||||
|
||||
@@ -188,11 +196,15 @@ pub fn get_updates<Resource: ResourceSync>(
|
||||
let config: Resource::Config = resource.config.into();
|
||||
resource.config = config.into();
|
||||
|
||||
let diff = Resource::get_diff(
|
||||
Resource::validate_partial_config(&mut resource.config);
|
||||
|
||||
let mut diff = Resource::get_diff(
|
||||
original.config.clone(),
|
||||
resource.config,
|
||||
)?;
|
||||
|
||||
Resource::validate_diff(&mut diff);
|
||||
|
||||
let original_tags = original
|
||||
.tags
|
||||
.iter()
|
||||
|
||||
@@ -78,6 +78,14 @@ impl ResourceSync for Build {
|
||||
Ok(original.partial_diff(update))
|
||||
}
|
||||
|
||||
fn validate_diff(diff: &mut Self::ConfigDiff) {
|
||||
if let Some((_, to)) = &diff.version {
|
||||
if to.is_none() {
|
||||
diff.version = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete(id: String) -> anyhow::Result<()> {
|
||||
monitor_client().write(DeleteBuild { id }).await?;
|
||||
Ok(())
|
||||
|
||||
@@ -30,11 +30,12 @@ use monitor_client::{
|
||||
},
|
||||
};
|
||||
use mungos::find::find_collect;
|
||||
use partial_derive2::PartialDiff;
|
||||
use resolver_api::Resolve;
|
||||
|
||||
use crate::{
|
||||
helpers::query::get_user_user_group_ids,
|
||||
resource,
|
||||
resource::{self, MonitorResource},
|
||||
state::{db_client, State},
|
||||
};
|
||||
|
||||
@@ -166,7 +167,9 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
PermissionLevel::Read,
|
||||
)
|
||||
.await?;
|
||||
res.alerters.push(convert_resource(alerter, &names.tags))
|
||||
res
|
||||
.alerters
|
||||
.push(convert_resource::<Alerter>(alerter, &names.tags))
|
||||
}
|
||||
ResourceTarget::ResourceSync(id) => {
|
||||
let sync = resource::get_check_permissions::<ResourceSync>(
|
||||
@@ -175,7 +178,9 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
PermissionLevel::Read,
|
||||
)
|
||||
.await?;
|
||||
res.resource_syncs.push(convert_resource(sync, &names.tags))
|
||||
res
|
||||
.resource_syncs
|
||||
.push(convert_resource::<ResourceSync>(sync, &names.tags))
|
||||
}
|
||||
ResourceTarget::ServerTemplate(id) => {
|
||||
let template = resource::get_check_permissions::<
|
||||
@@ -184,9 +189,9 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
&id, &user, PermissionLevel::Read
|
||||
)
|
||||
.await?;
|
||||
res
|
||||
.server_templates
|
||||
.push(convert_resource(template, &names.tags))
|
||||
res.server_templates.push(
|
||||
convert_resource::<ServerTemplate>(template, &names.tags),
|
||||
)
|
||||
}
|
||||
ResourceTarget::Server(id) => {
|
||||
let server = resource::get_check_permissions::<Server>(
|
||||
@@ -195,7 +200,9 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
PermissionLevel::Read,
|
||||
)
|
||||
.await?;
|
||||
res.servers.push(convert_resource(server, &names.tags))
|
||||
res
|
||||
.servers
|
||||
.push(convert_resource::<Server>(server, &names.tags))
|
||||
}
|
||||
ResourceTarget::Builder(id) => {
|
||||
let mut builder =
|
||||
@@ -211,7 +218,9 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
names.servers.get(&id).unwrap_or(&String::new()),
|
||||
)
|
||||
}
|
||||
res.builders.push(convert_resource(builder, &names.tags))
|
||||
res
|
||||
.builders
|
||||
.push(convert_resource::<Builder>(builder, &names.tags))
|
||||
}
|
||||
ResourceTarget::Build(id) => {
|
||||
let mut build = resource::get_check_permissions::<Build>(
|
||||
@@ -227,7 +236,9 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
.get(&build.config.builder_id)
|
||||
.unwrap_or(&String::new()),
|
||||
);
|
||||
res.builds.push(convert_resource(build, &names.tags))
|
||||
res
|
||||
.builds
|
||||
.push(convert_resource::<Build>(build, &names.tags))
|
||||
}
|
||||
ResourceTarget::Deployment(id) => {
|
||||
let mut deployment = resource::get_check_permissions::<
|
||||
@@ -251,9 +262,10 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
names.builds.get(build_id).unwrap_or(&String::new()),
|
||||
);
|
||||
}
|
||||
res
|
||||
.deployments
|
||||
.push(convert_resource(deployment, &names.tags))
|
||||
res.deployments.push(convert_resource::<Deployment>(
|
||||
deployment,
|
||||
&names.tags,
|
||||
))
|
||||
}
|
||||
ResourceTarget::Repo(id) => {
|
||||
let mut repo = resource::get_check_permissions::<Repo>(
|
||||
@@ -269,7 +281,7 @@ impl Resolve<ExportResourcesToToml, User> for State {
|
||||
.get(&repo.config.server_id)
|
||||
.unwrap_or(&String::new()),
|
||||
);
|
||||
res.repos.push(convert_resource(repo, &names.tags))
|
||||
res.repos.push(convert_resource::<Repo>(repo, &names.tags))
|
||||
}
|
||||
ResourceTarget::Procedure(id) => {
|
||||
add_procedure(&id, &mut res, &user, &names)
|
||||
@@ -381,7 +393,7 @@ async fn add_procedure(
|
||||
|
||||
res
|
||||
.procedures
|
||||
.push(convert_resource(procedure, &names.tags));
|
||||
.push(convert_resource::<Procedure>(procedure, &names.tags));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -500,13 +512,13 @@ async fn add_user_groups(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn convert_resource<Config, Info: Default, PartialConfig>(
|
||||
resource: Resource<Config, Info>,
|
||||
fn convert_resource<R: MonitorResource>(
|
||||
resource: Resource<R::Config, R::Info>,
|
||||
tag_names: &HashMap<String, String>,
|
||||
) -> ResourceToml<PartialConfig>
|
||||
where
|
||||
Config: Into<PartialConfig>,
|
||||
{
|
||||
) -> ResourceToml<R::PartialConfig> {
|
||||
// This makes sure all non-necessary (defaulted) fields don't make it into final toml
|
||||
let partial: R::PartialConfig = resource.config.into();
|
||||
let config = R::Config::default().minimize_partial(partial);
|
||||
ResourceToml {
|
||||
name: resource.name,
|
||||
tags: resource
|
||||
@@ -515,6 +527,6 @@ where
|
||||
.filter_map(|t| tag_names.get(t).cloned())
|
||||
.collect(),
|
||||
description: resource.description,
|
||||
config: resource.config.into(),
|
||||
config,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use monitor_client::{
|
||||
repo::Repo,
|
||||
server::Server,
|
||||
server_template::ServerTemplate,
|
||||
sync::{PendingUpdates, ResourceSync},
|
||||
sync::{PendingSyncUpdates, ResourceSync},
|
||||
user::User,
|
||||
},
|
||||
};
|
||||
@@ -105,7 +105,7 @@ impl Resolve<RefreshResourceSyncPending, User> for State {
|
||||
let all_resources = AllResourcesById::load().await?;
|
||||
let id_to_tags = get_id_to_tags(None).await?;
|
||||
|
||||
let pending = PendingUpdates {
|
||||
let pending = PendingSyncUpdates {
|
||||
hash,
|
||||
message,
|
||||
server_updates: get_updates_for_view::<Server>(
|
||||
|
||||
@@ -13,6 +13,7 @@ use monitor_client::{
|
||||
repo::Repo,
|
||||
server::Server,
|
||||
server_template::ServerTemplate,
|
||||
sync::SyncUpdate,
|
||||
tag::Tag,
|
||||
toml::ResourceToml,
|
||||
update::{Log, ResourceTarget},
|
||||
@@ -44,6 +45,10 @@ pub struct ToUpdateItem<T> {
|
||||
pub trait ResourceSync: MonitorResource + Sized {
|
||||
fn resource_target(id: String) -> ResourceTarget;
|
||||
|
||||
/// Apply any changes to incoming toml partial config
|
||||
/// before it is diffed against existing config
|
||||
fn validate_partial_config(_config: &mut Self::PartialConfig) {}
|
||||
|
||||
/// Diffs the declared toml (partial) against the full existing config.
|
||||
/// Removes all fields from toml (partial) that haven't changed.
|
||||
fn get_diff(
|
||||
@@ -52,6 +57,10 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
resources: &AllResourcesById,
|
||||
) -> anyhow::Result<Self::ConfigDiff>;
|
||||
|
||||
/// Apply any changes to computed config diff
|
||||
/// before logging
|
||||
fn validate_diff(_diff: &mut Self::ConfigDiff) {}
|
||||
|
||||
async fn run_updates(
|
||||
to_create: ToCreate<Self::PartialConfig>,
|
||||
to_update: ToUpdate<Self::PartialConfig>,
|
||||
@@ -194,7 +203,7 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
delete: bool,
|
||||
all_resources: &AllResourcesById,
|
||||
id_to_tags: &HashMap<String, Tag>,
|
||||
) -> anyhow::Result<Option<String>> {
|
||||
) -> anyhow::Result<Option<SyncUpdate>> {
|
||||
let map = find_collect(Resource::coll().await, None, None)
|
||||
.await
|
||||
.context("failed to get resources from db")?
|
||||
@@ -202,20 +211,21 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
.map(|r| (r.name.clone(), r))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let mut any_change = false;
|
||||
let mut update = SyncUpdate {
|
||||
log: format!("{} Updates", Resource::resource_type()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut to_delete = Vec::<String>::new();
|
||||
if delete {
|
||||
for resource in map.values() {
|
||||
if !resources.iter().any(|r| r.name == resource.name) {
|
||||
any_change = true;
|
||||
update.to_delete += 1;
|
||||
to_delete.push(resource.name.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut log = format!("{} Updates", Resource::resource_type());
|
||||
|
||||
for mut resource in resources {
|
||||
match map.get(&resource.name) {
|
||||
Some(original) => {
|
||||
@@ -224,12 +234,16 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
let config: Resource::Config = resource.config.into();
|
||||
resource.config = config.into();
|
||||
|
||||
let diff = Resource::get_diff(
|
||||
Resource::validate_partial_config(&mut resource.config);
|
||||
|
||||
let mut diff = Resource::get_diff(
|
||||
original.config.clone(),
|
||||
resource.config,
|
||||
all_resources,
|
||||
)?;
|
||||
|
||||
Resource::validate_diff(&mut diff);
|
||||
|
||||
let original_tags = original
|
||||
.tags
|
||||
.iter()
|
||||
@@ -245,9 +259,9 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
continue;
|
||||
}
|
||||
|
||||
any_change = true;
|
||||
update.to_update += 1;
|
||||
|
||||
log.push_str(&format!(
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: {}: '{}'\n-------------------",
|
||||
colored("UPDATE", "blue"),
|
||||
Resource::resource_type(),
|
||||
@@ -287,12 +301,12 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
)
|
||||
},
|
||||
));
|
||||
log.push('\n');
|
||||
log.push_str(&lines.join("\n-------------------\n"));
|
||||
update.log.push('\n');
|
||||
update.log.push_str(&lines.join("\n-------------------\n"));
|
||||
}
|
||||
None => {
|
||||
any_change = true;
|
||||
log.push_str(&format!(
|
||||
update.to_create += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: {}: {}\n{}: {}\n{}: {:?}\n{}: {}",
|
||||
colored("CREATE", "green"),
|
||||
Resource::resource_type(),
|
||||
@@ -310,7 +324,7 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
}
|
||||
|
||||
for name in to_delete {
|
||||
log.push_str(&format!(
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: {}: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
Resource::resource_type(),
|
||||
@@ -318,7 +332,11 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
));
|
||||
}
|
||||
|
||||
Ok(any_change.then_some(log))
|
||||
let any_change = update.to_create > 0
|
||||
|| update.to_update > 0
|
||||
|| update.to_delete > 0;
|
||||
|
||||
Ok(any_change.then_some(update))
|
||||
}
|
||||
|
||||
/// Gets all the resources to update. For use in sync execution.
|
||||
@@ -355,12 +373,16 @@ pub async fn get_updates_for_execution<Resource: ResourceSync>(
|
||||
let config: Resource::Config = resource.config.into();
|
||||
resource.config = config.into();
|
||||
|
||||
let diff = Resource::get_diff(
|
||||
Resource::validate_partial_config(&mut resource.config);
|
||||
|
||||
let mut diff = Resource::get_diff(
|
||||
original.config.clone(),
|
||||
resource.config,
|
||||
all_resources,
|
||||
)?;
|
||||
|
||||
Resource::validate_diff(&mut diff);
|
||||
|
||||
let original_tags = original
|
||||
.tags
|
||||
.iter()
|
||||
|
||||
@@ -63,6 +63,14 @@ impl ResourceSync for Build {
|
||||
|
||||
Ok(original.partial_diff(update))
|
||||
}
|
||||
|
||||
fn validate_diff(diff: &mut Self::ConfigDiff) {
|
||||
if let Some((_, to)) = &diff.version {
|
||||
if to.is_none() {
|
||||
diff.version = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResourceSync for Deployment {
|
||||
|
||||
@@ -11,6 +11,7 @@ use monitor_client::{
|
||||
},
|
||||
entities::{
|
||||
permission::UserTarget,
|
||||
sync::SyncUpdate,
|
||||
toml::{PermissionToml, UserGroupToml},
|
||||
update::{Log, ResourceTarget},
|
||||
user::sync_user,
|
||||
@@ -38,7 +39,7 @@ pub async fn get_updates_for_view(
|
||||
user_groups: Vec<UserGroupToml>,
|
||||
delete: bool,
|
||||
all_resources: &AllResourcesById,
|
||||
) -> anyhow::Result<Option<String>> {
|
||||
) -> anyhow::Result<Option<SyncUpdate>> {
|
||||
let map = find_collect(&db_client().await.user_groups, None, None)
|
||||
.await
|
||||
.context("failed to query db for UserGroups")?
|
||||
@@ -46,32 +47,22 @@ pub async fn get_updates_for_view(
|
||||
.map(|ug| (ug.name.clone(), ug))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let mut update = SyncUpdate {
|
||||
log: String::from("User Group Updates"),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut to_delete = Vec::<String>::new();
|
||||
|
||||
if delete {
|
||||
for user_group in map.values() {
|
||||
if !user_groups.iter().any(|ug| ug.name == user_group.name) {
|
||||
update.to_delete += 1;
|
||||
to_delete.push(user_group.name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut log = String::from("User Group Updates");
|
||||
|
||||
if user_groups.is_empty() {
|
||||
if to_delete.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
for name in &to_delete {
|
||||
log.push_str(&format!(
|
||||
"\n\n{}: user group: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
bold(name),
|
||||
));
|
||||
}
|
||||
return Ok(Some(log));
|
||||
}
|
||||
|
||||
let id_to_user = find_collect(&db_client().await.users, None, None)
|
||||
.await
|
||||
.context("failed to query db for Users")?
|
||||
@@ -83,7 +74,8 @@ pub async fn get_updates_for_view(
|
||||
let original = match map.get(&user_group.name).cloned() {
|
||||
Some(original) => original,
|
||||
None => {
|
||||
log.push_str(&format!(
|
||||
update.to_create += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: user group: {}\n{}: {:?}\n{}: {:?}",
|
||||
colored("CREATE", "green"),
|
||||
colored(&user_group.name, "green"),
|
||||
@@ -199,9 +191,10 @@ pub async fn get_updates_for_view(
|
||||
let update_permissions =
|
||||
user_group.permissions != original_permissions;
|
||||
|
||||
// only push update after failed diff
|
||||
// only add log after diff detected
|
||||
if update_users || update_permissions {
|
||||
log.push_str(&format!(
|
||||
update.to_update += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: user group: '{}'\n-------------------",
|
||||
colored("UPDATE", "blue"),
|
||||
bold(&user_group.name),
|
||||
@@ -269,20 +262,20 @@ pub async fn get_updates_for_view(
|
||||
muted("adding"),
|
||||
))
|
||||
}
|
||||
log.push('\n');
|
||||
log.push_str(&lines.join("\n-------------------\n"));
|
||||
update.log.push('\n');
|
||||
update.log.push_str(&lines.join("\n-------------------\n"));
|
||||
}
|
||||
}
|
||||
|
||||
for name in &to_delete {
|
||||
log.push_str(&format!(
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: user group: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
bold(name),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Some(log))
|
||||
Ok(Some(update))
|
||||
}
|
||||
|
||||
pub async fn get_updates_for_execution(
|
||||
|
||||
@@ -6,7 +6,10 @@ use monitor_client::{
|
||||
CreateVariable, DeleteVariable, UpdateVariableDescription,
|
||||
UpdateVariableValue,
|
||||
},
|
||||
entities::{update::Log, user::sync_user, variable::Variable},
|
||||
entities::{
|
||||
sync::SyncUpdate, update::Log, user::sync_user,
|
||||
variable::Variable,
|
||||
},
|
||||
};
|
||||
use mungos::find::find_collect;
|
||||
use resolver_api::Resolve;
|
||||
@@ -24,7 +27,7 @@ pub struct ToUpdateItem {
|
||||
pub async fn get_updates_for_view(
|
||||
variables: Vec<Variable>,
|
||||
delete: bool,
|
||||
) -> anyhow::Result<Option<String>> {
|
||||
) -> anyhow::Result<Option<SyncUpdate>> {
|
||||
let map = find_collect(&db_client().await.variables, None, None)
|
||||
.await
|
||||
.context("failed to query db for variables")?
|
||||
@@ -32,32 +35,22 @@ pub async fn get_updates_for_view(
|
||||
.map(|v| (v.name.clone(), v))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let mut update = SyncUpdate {
|
||||
log: String::from("Variable Updates"),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut to_delete = Vec::<String>::new();
|
||||
|
||||
if delete {
|
||||
for variable in map.values() {
|
||||
if !variables.iter().any(|v| v.name == variable.name) {
|
||||
update.to_delete += 1;
|
||||
to_delete.push(variable.name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut log = String::from("Variable Updates");
|
||||
|
||||
if variables.is_empty() {
|
||||
if to_delete.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
for name in &to_delete {
|
||||
log.push_str(&format!(
|
||||
"\n\n{}: variable: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
bold(name),
|
||||
));
|
||||
}
|
||||
return Ok(Some(log));
|
||||
}
|
||||
|
||||
for variable in variables {
|
||||
match map.get(&variable.name) {
|
||||
Some(original) => {
|
||||
@@ -70,7 +63,8 @@ pub async fn get_updates_for_view(
|
||||
if !item.update_value && !item.update_description {
|
||||
continue;
|
||||
}
|
||||
log.push_str(&format!(
|
||||
update.to_update += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: '{}'\n-------------------",
|
||||
colored("UPDATE", "blue"),
|
||||
bold(&item.variable.name),
|
||||
@@ -100,11 +94,12 @@ pub async fn get_updates_for_view(
|
||||
))
|
||||
}
|
||||
|
||||
log.push('\n');
|
||||
log.push_str(&lines.join("\n-------------------\n"));
|
||||
update.log.push('\n');
|
||||
update.log.push_str(&lines.join("\n-------------------\n"));
|
||||
}
|
||||
None => {
|
||||
log.push_str(&format!(
|
||||
update.to_create += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: {}\n{}: {}\n{}: {}",
|
||||
colored("CREATE", "green"),
|
||||
colored(&variable.name, "green"),
|
||||
@@ -118,14 +113,14 @@ pub async fn get_updates_for_view(
|
||||
}
|
||||
|
||||
for name in &to_delete {
|
||||
log.push_str(&format!(
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
bold(name),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Some(log))
|
||||
Ok(Some(update))
|
||||
}
|
||||
|
||||
pub async fn get_updates_for_execution(
|
||||
|
||||
@@ -64,6 +64,7 @@ pub use repo::{
|
||||
pub trait MonitorResource {
|
||||
type ListItem: Serialize + Send;
|
||||
type Config: Clone
|
||||
+ Default
|
||||
+ Send
|
||||
+ Sync
|
||||
+ Unpin
|
||||
|
||||
@@ -62,38 +62,51 @@ pub struct ResourceSyncInfo {
|
||||
/// Commit message of last applied sync
|
||||
pub last_sync_message: String,
|
||||
/// Readable logs of pending updates
|
||||
pub pending: PendingUpdates,
|
||||
pub pending: PendingSyncUpdates,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct PendingUpdates {
|
||||
pub struct SyncUpdate {
|
||||
/// Resources to create
|
||||
pub to_create: i32,
|
||||
/// Resources to update
|
||||
pub to_update: i32,
|
||||
/// Resources to delete
|
||||
pub to_delete: i32,
|
||||
/// A readable log of all the changes to be applied
|
||||
pub log: String,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct PendingSyncUpdates {
|
||||
/// The commit hash which produced these pending updates
|
||||
pub hash: String,
|
||||
/// The commit message which produced these pending updates
|
||||
pub message: String,
|
||||
/// Readable log of any pending server updates
|
||||
pub server_updates: Option<String>,
|
||||
pub server_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending deployment updates
|
||||
pub deployment_updates: Option<String>,
|
||||
pub deployment_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending build updates
|
||||
pub build_updates: Option<String>,
|
||||
pub build_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending repo updates
|
||||
pub repo_updates: Option<String>,
|
||||
pub repo_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending procedure updates
|
||||
pub procedure_updates: Option<String>,
|
||||
pub procedure_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending alerter updates
|
||||
pub alerter_updates: Option<String>,
|
||||
pub alerter_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending builder updates
|
||||
pub builder_updates: Option<String>,
|
||||
pub builder_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending server template updates
|
||||
pub server_template_updates: Option<String>,
|
||||
pub server_template_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending resource sync updates
|
||||
pub resource_sync_updates: Option<String>,
|
||||
pub resource_sync_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending variable updates
|
||||
pub variable_updates: Option<String>,
|
||||
pub variable_updates: Option<SyncUpdate>,
|
||||
/// Readable log of any pending user group updates
|
||||
pub user_group_updates: Option<String>,
|
||||
pub user_group_updates: Option<SyncUpdate>,
|
||||
}
|
||||
|
||||
#[typeshare(serialized_as = "Partial<ResourceSyncConfig>")]
|
||||
|
||||
@@ -1174,33 +1174,44 @@ export interface ResourceSyncConfig {
|
||||
webhook_enabled: boolean;
|
||||
}
|
||||
|
||||
export interface PendingUpdates {
|
||||
export interface SyncUpdate {
|
||||
/** Resources to create */
|
||||
to_create: number;
|
||||
/** Resources to update */
|
||||
to_update: number;
|
||||
/** Resources to delete */
|
||||
to_delete: number;
|
||||
/** A readable log of all the changes to be applied */
|
||||
log: string;
|
||||
}
|
||||
|
||||
export interface PendingSyncUpdates {
|
||||
/** The commit hash which produced these pending updates */
|
||||
hash: string;
|
||||
/** The commit message which produced these pending updates */
|
||||
message: string;
|
||||
/** Readable log of any pending server updates */
|
||||
server_updates?: string;
|
||||
server_updates?: SyncUpdate;
|
||||
/** Readable log of any pending deployment updates */
|
||||
deployment_updates?: string;
|
||||
deployment_updates?: SyncUpdate;
|
||||
/** Readable log of any pending build updates */
|
||||
build_updates?: string;
|
||||
build_updates?: SyncUpdate;
|
||||
/** Readable log of any pending repo updates */
|
||||
repo_updates?: string;
|
||||
repo_updates?: SyncUpdate;
|
||||
/** Readable log of any pending procedure updates */
|
||||
procedure_updates?: string;
|
||||
procedure_updates?: SyncUpdate;
|
||||
/** Readable log of any pending alerter updates */
|
||||
alerter_updates?: string;
|
||||
alerter_updates?: SyncUpdate;
|
||||
/** Readable log of any pending builder updates */
|
||||
builder_updates?: string;
|
||||
builder_updates?: SyncUpdate;
|
||||
/** Readable log of any pending server template updates */
|
||||
server_template_updates?: string;
|
||||
server_template_updates?: SyncUpdate;
|
||||
/** Readable log of any pending resource sync updates */
|
||||
resource_sync_updates?: string;
|
||||
resource_sync_updates?: SyncUpdate;
|
||||
/** Readable log of any pending variable updates */
|
||||
variable_updates?: string;
|
||||
variable_updates?: SyncUpdate;
|
||||
/** Readable log of any pending user group updates */
|
||||
user_group_updates?: string;
|
||||
user_group_updates?: SyncUpdate;
|
||||
}
|
||||
|
||||
export interface ResourceSyncInfo {
|
||||
@@ -1211,7 +1222,7 @@ export interface ResourceSyncInfo {
|
||||
/** Commit message of last applied sync */
|
||||
last_sync_message: string;
|
||||
/** Readable logs of pending updates */
|
||||
pending: PendingUpdates;
|
||||
pending: PendingSyncUpdates;
|
||||
}
|
||||
|
||||
export type ResourceSync = Resource<ResourceSyncConfig, ResourceSyncInfo>;
|
||||
|
||||
@@ -46,7 +46,11 @@ const PendingOrConfig = ({ id }: { id: string }) => {
|
||||
|
||||
const tabsList = (
|
||||
<TabsList className="justify-start w-fit">
|
||||
<TabsTrigger value="Pending" className="w-[110px]" disabled={true}>
|
||||
<TabsTrigger
|
||||
value="Pending"
|
||||
className="w-[110px]"
|
||||
disabled={pendingDisabled}
|
||||
>
|
||||
Pending
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="Config" className="w-[110px]">
|
||||
@@ -65,7 +69,7 @@ const PendingOrConfig = ({ id }: { id: string }) => {
|
||||
<PendingView
|
||||
key={type}
|
||||
type={type}
|
||||
log={sync?.info?.pending?.[key]}
|
||||
pending={sync?.info?.pending?.[key]}
|
||||
/>
|
||||
))}
|
||||
</Section>
|
||||
@@ -76,22 +80,39 @@ const PendingOrConfig = ({ id }: { id: string }) => {
|
||||
|
||||
const PendingView = ({
|
||||
type,
|
||||
log,
|
||||
pending,
|
||||
}: {
|
||||
type: string;
|
||||
log: string | undefined;
|
||||
pending: Types.SyncUpdate | undefined;
|
||||
}) => {
|
||||
if (!log) return;
|
||||
if (!pending) return;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex-col">
|
||||
<CardHeader className="flex items-center justify-between gap-4">
|
||||
<CardTitle>{type} Updates</CardTitle>
|
||||
<div className="flex gap-4 items-center">
|
||||
{pending.to_create && (
|
||||
<div className="flex gap-2 items-center">
|
||||
To Create: {pending.to_create}
|
||||
</div>
|
||||
)}
|
||||
{pending.to_update && (
|
||||
<div className="flex gap-2 items-center">
|
||||
To Update: {pending.to_update}
|
||||
</div>
|
||||
)}
|
||||
{pending.to_delete && (
|
||||
<div className="flex gap-2 items-center">
|
||||
To Delete: {pending.to_delete}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<pre
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: sanitizeOnlySpan(log),
|
||||
__html: sanitizeOnlySpan(pending.log),
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
|
||||
@@ -180,16 +180,16 @@ export const sync_no_changes = (sync: Types.ResourceSync) => {
|
||||
const pending = sync.info?.pending;
|
||||
if (!pending) return false;
|
||||
return (
|
||||
!pending.server_updates?.length &&
|
||||
!pending.deployment_updates?.length &&
|
||||
!pending.build_updates?.length &&
|
||||
!pending.repo_updates?.length &&
|
||||
!pending.procedure_updates?.length &&
|
||||
!pending.alerter_updates?.length &&
|
||||
!pending.builder_updates?.length &&
|
||||
!pending.server_template_updates?.length &&
|
||||
!pending.resource_sync_updates?.length &&
|
||||
!pending.variable_updates?.length &&
|
||||
!pending.user_group_updates?.length
|
||||
!pending.server_updates &&
|
||||
!pending.deployment_updates &&
|
||||
!pending.build_updates &&
|
||||
!pending.repo_updates &&
|
||||
!pending.procedure_updates &&
|
||||
!pending.alerter_updates &&
|
||||
!pending.builder_updates &&
|
||||
!pending.server_template_updates &&
|
||||
!pending.resource_sync_updates &&
|
||||
!pending.variable_updates &&
|
||||
!pending.user_group_updates
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user