forked from github-starred/komodo
abit more
This commit is contained in:
@@ -27,6 +27,7 @@ pub trait ResourceSync: Sized {
|
||||
+ Default
|
||||
+ Send
|
||||
+ From<Self::PartialConfig>
|
||||
+ PartialDiff<Self::PartialConfig, Self::ConfigDiff>
|
||||
+ 'static;
|
||||
type Info: Default + 'static;
|
||||
type PartialConfig: std::fmt::Debug
|
||||
@@ -35,7 +36,9 @@ pub trait ResourceSync: Sized {
|
||||
+ From<Self::Config>
|
||||
+ Serialize
|
||||
+ MaybeNone
|
||||
+ From<Self::ConfigDiff>
|
||||
+ 'static;
|
||||
type ConfigDiff: Diff + MaybeNone;
|
||||
|
||||
fn name_to_resource(
|
||||
) -> &'static HashMap<String, Resource<Self::Config, Self::Info>>;
|
||||
@@ -68,29 +71,24 @@ pub trait ResourceSync: Sized {
|
||||
id: String,
|
||||
description: String,
|
||||
) -> anyhow::Result<()>;
|
||||
}
|
||||
|
||||
pub trait ResourceSyncOuter<
|
||||
Implementer: ResourceSync,
|
||||
Logger: SyncLogger<Implementer, Self>,
|
||||
> where
|
||||
Self: Sized,
|
||||
Implementer::Config:
|
||||
PartialDiff<Implementer::PartialConfig, Self::ConfigDiff>,
|
||||
Implementer::PartialConfig: From<Self::ConfigDiff>,
|
||||
{
|
||||
type ConfigDiff: Diff + MaybeNone;
|
||||
|
||||
fn display() -> &'static str;
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget;
|
||||
|
||||
/// Diffs the declared toml (partial) against the full existing config.
|
||||
/// Removes all fields from toml (partial) that haven't changed.
|
||||
fn get_diff(
|
||||
original: Implementer::Config,
|
||||
update: Implementer::PartialConfig,
|
||||
original: Self::Config,
|
||||
update: Self::PartialConfig,
|
||||
) -> anyhow::Result<Self::ConfigDiff>;
|
||||
}
|
||||
|
||||
pub trait ResourceSyncOuter<
|
||||
Implementer: ResourceSync,
|
||||
Logger: SyncLogger<Implementer>,
|
||||
> where
|
||||
Self: Sized,
|
||||
{
|
||||
fn display() -> &'static str;
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget;
|
||||
|
||||
#[allow(async_fn_in_trait)]
|
||||
async fn run_updates(
|
||||
@@ -203,14 +201,9 @@ pub trait ResourceSyncOuter<
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SyncLogger<Implementer, Resource>
|
||||
pub trait SyncLogger<Implementer: ResourceSync>
|
||||
where
|
||||
Self: Sized,
|
||||
Implementer: ResourceSync,
|
||||
Resource: ResourceSyncOuter<Implementer, Self>,
|
||||
Implementer::Config:
|
||||
PartialDiff<Implementer::PartialConfig, Resource::ConfigDiff>,
|
||||
Implementer::PartialConfig: From<Resource::ConfigDiff>,
|
||||
{
|
||||
fn log_to_create(
|
||||
resource: &ResourceToml<Implementer::PartialConfig>,
|
||||
@@ -219,7 +212,7 @@ where
|
||||
name: &str,
|
||||
description: &str,
|
||||
tags: &[String],
|
||||
diff: &Resource::ConfigDiff,
|
||||
diff: &Implementer::ConfigDiff,
|
||||
);
|
||||
fn log_to_delete(name: &str);
|
||||
|
||||
@@ -237,6 +230,8 @@ where
|
||||
|
||||
fn log_description_updated(name: &str);
|
||||
fn log_failed_description_update(name: &str, e: anyhow::Error);
|
||||
|
||||
fn log_procedure_sync_failed_max_iter();
|
||||
}
|
||||
|
||||
pub trait IdToTag {
|
||||
@@ -251,11 +246,8 @@ pub fn get_updates<Implementer, Resource, Tags, Logger>(
|
||||
where
|
||||
Implementer: ResourceSync,
|
||||
Resource: ResourceSyncOuter<Implementer, Logger>,
|
||||
Implementer::Config:
|
||||
PartialDiff<Implementer::PartialConfig, Resource::ConfigDiff>,
|
||||
Implementer::PartialConfig: From<Resource::ConfigDiff>,
|
||||
Tags: IdToTag,
|
||||
Logger: SyncLogger<Implementer, Resource>,
|
||||
Logger: SyncLogger<Implementer>,
|
||||
{
|
||||
let map = Implementer::name_to_resource();
|
||||
|
||||
@@ -279,7 +271,7 @@ where
|
||||
let config: Implementer::Config = resource.config.into();
|
||||
resource.config = config.into();
|
||||
|
||||
let diff = Resource::get_diff(
|
||||
let diff = Implementer::get_diff(
|
||||
original.config.clone(),
|
||||
resource.config,
|
||||
)?;
|
||||
@@ -400,10 +392,7 @@ pub async fn run_update_tags<Implementer, Resource, Logger>(
|
||||
) where
|
||||
Implementer: ResourceSync,
|
||||
Resource: ResourceSyncOuter<Implementer, Logger>,
|
||||
Implementer::Config:
|
||||
PartialDiff<Implementer::PartialConfig, Resource::ConfigDiff>,
|
||||
Implementer::PartialConfig: From<Resource::ConfigDiff>,
|
||||
Logger: SyncLogger<Implementer, Resource>,
|
||||
Logger: SyncLogger<Implementer>,
|
||||
{
|
||||
// Update tags
|
||||
if let Err(e) = Implementer::update_tags(id, tags).await {
|
||||
@@ -430,10 +419,7 @@ pub async fn run_update_description<Implementer, Resource, Logger>(
|
||||
) where
|
||||
Implementer: ResourceSync,
|
||||
Resource: ResourceSyncOuter<Implementer, Logger>,
|
||||
Implementer::Config:
|
||||
PartialDiff<Implementer::PartialConfig, Resource::ConfigDiff>,
|
||||
Implementer::PartialConfig: From<Resource::ConfigDiff>,
|
||||
Logger: SyncLogger<Implementer, Resource>,
|
||||
Logger: SyncLogger<Implementer>,
|
||||
{
|
||||
if let Err(e) =
|
||||
Implementer::update_description(id, description).await
|
||||
|
||||
243
lib/sync/src/resources.rs
Normal file
243
lib/sync/src/resources.rs
Normal file
@@ -0,0 +1,243 @@
|
||||
use monitor_client::entities::{
|
||||
alerter::Alerter, build::Build, builder::Builder,
|
||||
deployment::Deployment, procedure::Procedure, repo::Repo,
|
||||
server::Server, server_template::ServerTemplate, sync,
|
||||
update::ResourceTarget,
|
||||
};
|
||||
use partial_derive2::MaybeNone;
|
||||
|
||||
use crate::resource::{
|
||||
ResourceSync, ResourceSyncOuter, SyncLogger, ToUpdateItem,
|
||||
};
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Server
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"server"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Server(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Deployment
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"deployment"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Deployment(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Build
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"build"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Build(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Repo
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"repo"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Repo(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Alerter
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"alerter"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Alerter(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Builder
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"builder"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Builder(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for ServerTemplate
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"server_template"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::ServerTemplate(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for sync::ResourceSync
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"resource_sync"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::ResourceSync(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Implementer: ResourceSync, Logger: SyncLogger<Implementer>>
|
||||
ResourceSyncOuter<Implementer, Logger> for Procedure
|
||||
{
|
||||
fn display() -> &'static str {
|
||||
"procedure"
|
||||
}
|
||||
|
||||
fn resource_target(id: String) -> ResourceTarget {
|
||||
ResourceTarget::Procedure(id)
|
||||
}
|
||||
|
||||
async fn run_updates(
|
||||
mut to_create: crate::resource::ToCreate<
|
||||
<Implementer as ResourceSync>::PartialConfig,
|
||||
>,
|
||||
mut to_update: crate::resource::ToUpdate<
|
||||
<Implementer as ResourceSync>::PartialConfig,
|
||||
>,
|
||||
to_delete: crate::resource::ToDelete,
|
||||
) {
|
||||
for name in to_delete {
|
||||
if let Err(e) = Implementer::delete(name.clone()).await {
|
||||
Logger::log_failed_delete(&name, e);
|
||||
// warn!("failed to delete procedure {name} | {e:#}",);
|
||||
} else {
|
||||
Logger::log_deleted(&name);
|
||||
// info!(
|
||||
// "{} procedure '{}'",
|
||||
// "deleted".red().bold(),
|
||||
// name.bold(),
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
if to_update.is_empty() && to_create.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
for i in 0..10 {
|
||||
let mut to_pull = Vec::new();
|
||||
for ToUpdateItem {
|
||||
id,
|
||||
resource,
|
||||
update_description,
|
||||
update_tags,
|
||||
} in &to_update
|
||||
{
|
||||
// Update resource
|
||||
let name = resource.name.clone();
|
||||
let tags = resource.tags.clone();
|
||||
let description = resource.description.clone();
|
||||
if *update_description {
|
||||
crate::resource::run_update_description::<
|
||||
Implementer,
|
||||
Self,
|
||||
Logger,
|
||||
>(id.clone(), &name, description)
|
||||
.await;
|
||||
}
|
||||
if *update_tags {
|
||||
crate::resource::run_update_tags::<Implementer, Self, Logger>(
|
||||
id.clone(),
|
||||
&name,
|
||||
tags,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
if !resource.config.is_none() {
|
||||
if let Err(e) =
|
||||
Implementer::update(id.clone(), resource.clone()).await
|
||||
{
|
||||
if i == 9 {
|
||||
Logger::log_failed_update(&name, e);
|
||||
// warn!(
|
||||
// "failed to update {} {name} | {e:#}",
|
||||
// Self::display()
|
||||
// );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// info!("{} {name} updated", Self::display());
|
||||
Logger::log_updated(&name);
|
||||
|
||||
// have to clone out so to_update is mutable
|
||||
to_pull.push(id.clone());
|
||||
}
|
||||
//
|
||||
to_update.retain(|resource| !to_pull.contains(&resource.id));
|
||||
|
||||
let mut to_pull = Vec::new();
|
||||
for resource in &to_create {
|
||||
let name = resource.name.clone();
|
||||
let tags = resource.tags.clone();
|
||||
let description = resource.description.clone();
|
||||
let id = match Implementer::create(resource.clone()).await {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
if i == 9 {
|
||||
// warn!(
|
||||
// "failed to create {} {name} | {e:#}",
|
||||
// Self::display(),
|
||||
// );
|
||||
Logger::log_failed_create(&name, e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
crate::resource::run_update_tags::<Implementer, Self, Logger>(
|
||||
id.clone(),
|
||||
&name,
|
||||
tags,
|
||||
)
|
||||
.await;
|
||||
crate::resource::run_update_description::<
|
||||
Implementer,
|
||||
Self,
|
||||
Logger,
|
||||
>(id, &name, description)
|
||||
.await;
|
||||
Logger::log_created(&name);
|
||||
// info!("{} {name} created", Self::display());
|
||||
to_pull.push(name);
|
||||
}
|
||||
to_create.retain(|resource| !to_pull.contains(&resource.name));
|
||||
|
||||
if to_update.is_empty() && to_create.is_empty() {
|
||||
// info!("all procedures synced");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Logger::log_procedure_sync_failed_max_iter();
|
||||
// warn!("procedure sync loop exited after max iterations");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user