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