resources sync ready for test

This commit is contained in:
mbecker20
2024-03-26 04:25:00 -07:00
parent 73217c9178
commit f1c9d05abc
10 changed files with 707 additions and 498 deletions
+219 -11
View File
@@ -1,16 +1,27 @@
use std::path::Path;
use std::{collections::HashMap, path::Path};
use monitor_client::entities::{
alerter::Alerter, build::Build, builder::Builder,
deployment::Deployment, repo::Repo, server::Server,
use async_trait::async_trait;
use monitor_client::{
api::{
read::ListTags,
write::{CreateTag, UpdateDescription, UpdateTagsOnResource},
},
entities::{
alerter::Alerter,
build::Build,
builder::Builder,
deployment::Deployment,
repo::Repo,
resource::{Resource, ResourceListItem},
server::Server,
update::ResourceTarget,
},
};
use crate::wait_for_enter;
use crate::{monitor_client, wait_for_enter};
mod resource_file;
mod sync_trait;
use sync_trait::Sync;
mod resources;
pub async fn run_sync(path: &Path) -> anyhow::Result<()> {
info!("path: {path:?}");
@@ -32,13 +43,210 @@ pub async fn run_sync(path: &Path) -> anyhow::Result<()> {
wait_for_enter("CONTINUE")?;
Build::run_updates(build_updates, build_creates).await;
// Run these first, which require no name -> id replacement
Builder::run_updates(builder_updates, builder_creates).await;
Server::run_updates(server_updates, server_creates).await;
Alerter::run_updates(alerter_updates, alerter_creates).await;
Build::run_updates(build_updates, build_creates).await;
Deployment::run_updates(deployment_updates, deployment_creates)
.await;
Builder::run_updates(builder_updates, builder_creates).await;
Alerter::run_updates(alerter_updates, alerter_creates).await;
Repo::run_updates(repo_updates, repo_creates).await;
Ok(())
}
type ToUpdate<T> = Vec<(String, Resource<T>)>;
type ToCreate<T> = Vec<Resource<T>>;
type UpdatesResult<T> = (ToUpdate<T>, ToCreate<T>);
#[async_trait]
pub trait ResourceSync {
type PartialConfig: Clone + Send + 'static;
type ListItemInfo: 'static;
type ExtLookup: Send + Sync;
fn display() -> &'static str;
fn resource_target(id: String) -> ResourceTarget;
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>;
async fn init_lookup_data() -> Self::ExtLookup;
/// Returns created id
async fn create(
resource: Resource<Self::PartialConfig>,
ext_lookup: &Self::ExtLookup,
) -> anyhow::Result<String>;
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
ext_lookup: &Self::ExtLookup,
) -> anyhow::Result<()>;
fn get_updates(
resources: Vec<Resource<Self::PartialConfig>>,
) -> anyhow::Result<UpdatesResult<Self::PartialConfig>> {
let map = Self::name_to_resource();
// (name, partial config)
let mut to_update =
Vec::<(String, Resource<Self::PartialConfig>)>::new();
let mut to_create = Vec::<Resource<Self::PartialConfig>>::new();
for resource in resources {
match map.get(&resource.name).map(|s| s.id.clone()) {
Some(id) => {
to_update.push((id, resource));
}
None => {
to_create.push(resource);
}
}
}
if !to_create.is_empty() {
println!(
"\nTO CREATE: {}",
to_create
.iter()
.map(|item| item.name.as_str())
.collect::<Vec<_>>()
.join(", ")
);
}
if !to_update.is_empty() {
println!(
"\nTO UPDATE: {}",
to_update
.iter()
.map(|(_, item)| item.name.as_str())
.collect::<Vec<_>>()
.join(", ")
);
}
Ok((to_update, to_create))
}
async fn run_updates(
to_update: ToUpdate<Self::PartialConfig>,
to_create: ToCreate<Self::PartialConfig>,
) {
let mut tag_name_to_id = monitor_client()
.read(ListTags::default())
.await
.expect("failed to ListTags mid run")
.into_iter()
.map(|tag| (tag.name, tag.id))
.collect::<HashMap<_, _>>();
let ext_lookup = Self::init_lookup_data().await;
for (id, resource) in to_update {
// Update resource
let name = resource.name.clone();
let tags = resource.tags.clone();
let description = resource.description.clone();
if let Err(e) =
Self::update(id.clone(), resource, &ext_lookup).await
{
warn!("failed to update {} {name} | {e:#}", Self::display());
}
Self::update_tags(
id.clone(),
&name,
&tags,
&mut tag_name_to_id,
)
.await;
Self::update_description(id, description).await;
}
for resource in to_create {
let name = resource.name.clone();
let tags = resource.tags.clone();
let description = resource.description.clone();
let id = match Self::create(resource, &ext_lookup).await {
Ok(id) => id,
Err(e) => {
warn!(
"failed to create {} {name} | {e:#}",
Self::display(),
);
continue;
}
};
Self::update_tags(
id.clone(),
&name,
&tags,
&mut tag_name_to_id,
)
.await;
Self::update_description(id, description).await;
}
}
async fn update_tags(
resource_id: String,
resource_name: &str,
tags: &[String],
tag_name_to_id: &mut HashMap<String, String>,
) {
// make sure all tags are created
for tag_name in tags {
if !tag_name_to_id.contains_key(tag_name) {
let tag_id = monitor_client()
.write(CreateTag {
name: tag_name.to_string(),
})
.await
.expect("failed to CreateTag mid run")
.id;
tag_name_to_id.insert(tag_name.to_string(), tag_id);
}
}
// get Vec<tag_id>
let tags = tags
.iter()
.map(|tag_name| {
tag_name_to_id
.get(tag_name)
.expect("somehow didn't find tag at this point")
.to_string()
})
.collect();
// Update tags
if let Err(e) = monitor_client()
.write(UpdateTagsOnResource {
target: Self::resource_target(resource_id),
tags,
})
.await
{
warn!(
"failed to update tags on {} {resource_name} | {e:#}",
Self::display(),
);
}
}
async fn update_description(id: String, description: String) {
if let Err(e) = monitor_client()
.write(UpdateDescription {
target: Self::resource_target(id.clone()),
description,
})
.await
{
warn!("failed to update resource {id} description | {e:#}");
}
}
}
+67
View File
@@ -0,0 +1,67 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::write::{CreateAlerter, UpdateAlerter},
entities::{
alerter::{Alerter, AlerterListItemInfo, PartialAlerterConfig},
resource::{Resource, ResourceListItem},
update::ResourceTarget,
},
};
use crate::{
maps::name_to_alerter, monitor_client, sync::ResourceSync,
};
#[async_trait]
impl ResourceSync for Alerter {
type PartialConfig = PartialAlerterConfig;
type ListItemInfo = AlerterListItemInfo;
type ExtLookup = ();
fn display() -> &'static str {
"alerter"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Alerter(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_alerter()
}
async fn init_lookup_data() -> Self::ExtLookup {
()
}
async fn create(
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<String> {
monitor_client()
.write(CreateAlerter {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<()> {
monitor_client()
.write(UpdateAlerter {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
+88
View File
@@ -0,0 +1,88 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::{
read::ListBuilders,
write::{CreateBuild, UpdateBuild},
},
entities::{
build::{Build, BuildListItemInfo, PartialBuildConfig},
resource::{Resource, ResourceListItem},
update::ResourceTarget,
},
};
use crate::{
maps::name_to_build, monitor_client, sync::ResourceSync,
};
#[async_trait]
impl ResourceSync for Build {
type PartialConfig = PartialBuildConfig;
type ListItemInfo = BuildListItemInfo;
/// Builder Name to Id
type ExtLookup = HashMap<String, String>;
fn display() -> &'static str {
"build"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Build(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_build()
}
async fn init_lookup_data() -> Self::ExtLookup {
monitor_client()
.read(ListBuilders::default())
.await
.expect("failed to get builders")
.into_iter()
.map(|b| (b.name, b.id))
.collect::<HashMap<_, _>>()
}
async fn create(
mut resource: Resource<Self::PartialConfig>,
builder_name_to_id: &Self::ExtLookup,
) -> anyhow::Result<String> {
// at this point the 'builder_id' is the name
resource.config.builder_id = resource
.config
.builder_id
.and_then(|id| builder_name_to_id.get(&id).cloned());
monitor_client()
.write(CreateBuild {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
mut resource: Resource<Self::PartialConfig>,
builder_name_to_id: &Self::ExtLookup,
) -> anyhow::Result<()> {
// at this point the 'builder_id' is the name
resource.config.builder_id = resource
.config
.builder_id
.and_then(|id| builder_name_to_id.get(&id).cloned());
monitor_client()
.write(UpdateBuild {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
+67
View File
@@ -0,0 +1,67 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::write::{CreateBuilder, UpdateBuilder},
entities::{
builder::{Builder, BuilderListItemInfo, PartialBuilderConfig},
resource::{Resource, ResourceListItem},
update::ResourceTarget,
},
};
use crate::{
maps::name_to_builder, monitor_client, sync::ResourceSync,
};
#[async_trait]
impl ResourceSync for Builder {
type PartialConfig = PartialBuilderConfig;
type ListItemInfo = BuilderListItemInfo;
type ExtLookup = ();
fn display() -> &'static str {
"builder"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Builder(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_builder()
}
async fn init_lookup_data() -> Self::ExtLookup {
()
}
async fn create(
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<String> {
monitor_client()
.write(CreateBuilder {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<()> {
monitor_client()
.write(UpdateBuilder {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
+127
View File
@@ -0,0 +1,127 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::{
read::{ListBuilds, ListServers},
write,
},
entities::{
deployment::{
Deployment, DeploymentImage, DeploymentListItemInfo,
PartialDeploymentConfig,
},
resource::{Resource, ResourceListItem},
update::ResourceTarget,
},
};
use crate::{
maps::name_to_deployment, monitor_client, sync::ResourceSync,
};
pub struct DeploymentExtLookup {
pub servers: HashMap<String, String>,
pub builds: HashMap<String, String>,
}
#[async_trait]
impl ResourceSync for Deployment {
type PartialConfig = PartialDeploymentConfig;
type ListItemInfo = DeploymentListItemInfo;
type ExtLookup = DeploymentExtLookup;
fn display() -> &'static str {
"deployment"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Deployment(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_deployment()
}
async fn init_lookup_data() -> Self::ExtLookup {
let servers = monitor_client()
.read(ListServers::default())
.await
.expect("failed to get servers")
.into_iter()
.map(|b| (b.name, b.id))
.collect::<HashMap<_, _>>();
let builds = monitor_client()
.read(ListBuilds::default())
.await
.expect("failed to get builds")
.into_iter()
.map(|b| (b.name, b.id))
.collect::<HashMap<_, _>>();
DeploymentExtLookup { servers, builds }
}
async fn create(
mut resource: Resource<Self::PartialConfig>,
lookup: &Self::ExtLookup,
) -> anyhow::Result<String> {
handle_name_to_id_switch(&mut resource.config, lookup);
monitor_client()
.write(write::CreateDeployment {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
mut resource: Resource<Self::PartialConfig>,
lookup: &Self::ExtLookup,
) -> anyhow::Result<()> {
handle_name_to_id_switch(&mut resource.config, lookup);
monitor_client()
.write(write::UpdateDeployment {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
fn handle_name_to_id_switch(
config: &mut PartialDeploymentConfig,
lookup: &DeploymentExtLookup,
) {
config.server_id = config
.server_id
.as_ref()
.and_then(|name| lookup.servers.get(name).cloned());
if let Some(DeploymentImage::Build {
build_id: name,
version,
}) = &config.image
{
match lookup.builds.get(name).cloned() {
Some(build_id) => {
config.image = DeploymentImage::Build {
build_id,
version: version.clone(),
}
.into();
}
None => {
config.image = DeploymentImage::Image {
image: String::new(),
}
.into();
}
}
}
}
+7
View File
@@ -0,0 +1,7 @@
pub mod alerter;
pub mod build;
pub mod builder;
pub mod deployment;
pub mod procedure;
pub mod repo;
pub mod server;
+65
View File
@@ -0,0 +1,65 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::write::{CreateRepo, UpdateRepo},
entities::{
repo::{PartialRepoConfig, Repo, RepoInfo},
resource::{Resource, ResourceListItem},
update::ResourceTarget,
},
};
use crate::{maps::name_to_repo, monitor_client, sync::ResourceSync};
#[async_trait]
impl ResourceSync for Repo {
type PartialConfig = PartialRepoConfig;
type ListItemInfo = RepoInfo;
type ExtLookup = ();
fn display() -> &'static str {
"repo"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Repo(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_repo()
}
async fn init_lookup_data() -> Self::ExtLookup {
()
}
async fn create(
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<String> {
monitor_client()
.write(CreateRepo {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<()> {
monitor_client()
.write(UpdateRepo {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
+67
View File
@@ -0,0 +1,67 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::write::{CreateServer, UpdateServer},
entities::{
resource::{Resource, ResourceListItem},
server::{PartialServerConfig, Server, ServerListItemInfo},
update::ResourceTarget,
},
};
use crate::{
maps::name_to_server, monitor_client, sync::ResourceSync,
};
#[async_trait]
impl ResourceSync for Server {
type ListItemInfo = ServerListItemInfo;
type PartialConfig = PartialServerConfig;
type ExtLookup = ();
fn display() -> &'static str {
"server"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Server(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_server()
}
async fn init_lookup_data() -> Self::ExtLookup {
()
}
async fn create(
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<String> {
monitor_client()
.write(CreateServer {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
_: &(),
) -> anyhow::Result<()> {
monitor_client()
.write(UpdateServer {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
-487
View File
@@ -1,487 +0,0 @@
use std::collections::HashMap;
use async_trait::async_trait;
use monitor_client::{
api::{
read::ListTags,
write::{
self, CreateTag, UpdateDescription, UpdateTagsOnResource,
},
},
entities::{
alerter::{Alerter, AlerterListItemInfo, PartialAlerterConfig},
build::{Build, BuildListItemInfo, PartialBuildConfig},
builder::{Builder, BuilderListItemInfo, PartialBuilderConfig},
deployment::{
Deployment, DeploymentListItemInfo, PartialDeploymentConfig,
},
repo::{PartialRepoConfig, Repo, RepoInfo},
resource::{Resource, ResourceListItem},
server::{PartialServerConfig, Server, ServerListItemInfo},
update::ResourceTarget,
},
};
use crate::{
maps::{
name_to_alerter, name_to_build, name_to_builder,
name_to_deployment, name_to_repo, name_to_server,
},
monitor_client,
};
type ToUpdate<T> = Vec<(String, Resource<T>)>;
type ToCreate<T> = Vec<Resource<T>>;
type UpdatesResult<T> = (ToUpdate<T>, ToCreate<T>);
#[async_trait]
pub trait Sync {
type PartialConfig: Clone + Send + 'static;
type ListItemInfo: 'static;
fn display() -> &'static str;
fn resource_target(id: String) -> ResourceTarget;
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>;
/// Returns created id
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String>;
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()>;
fn get_updates(
resources: Vec<Resource<Self::PartialConfig>>,
) -> anyhow::Result<UpdatesResult<Self::PartialConfig>> {
let map = Self::name_to_resource();
// (name, partial config)
let mut to_update =
Vec::<(String, Resource<Self::PartialConfig>)>::new();
let mut to_create = Vec::<Resource<Self::PartialConfig>>::new();
for resource in resources {
match map.get(&resource.name).map(|s| s.id.clone()) {
Some(id) => {
to_update.push((id, resource));
}
None => {
to_create.push(resource);
}
}
}
if !to_create.is_empty() {
println!(
"\nTO CREATE: {}",
to_create
.iter()
.map(|item| item.name.as_str())
.collect::<Vec<_>>()
.join(", ")
);
}
if !to_update.is_empty() {
println!(
"\nTO UPDATE: {}",
to_update
.iter()
.map(|(_, item)| item.name.as_str())
.collect::<Vec<_>>()
.join(", ")
);
}
Ok((to_update, to_create))
}
async fn run_updates(
to_update: ToUpdate<Self::PartialConfig>,
to_create: ToCreate<Self::PartialConfig>,
) {
let mut tag_name_to_id = monitor_client()
.read(ListTags::default())
.await
.expect("failed to ListTags mid run")
.into_iter()
.map(|tag| (tag.name, tag.id))
.collect::<HashMap<_, _>>();
for (id, resource) in to_update {
// Update resource
let name = resource.name.clone();
let tags = resource.tags.clone();
let description = resource.description.clone();
if let Err(e) = Self::update(id.clone(), resource).await {
warn!("failed to update {} {name} | {e:#}", Self::display());
}
Self::update_tags(
id.clone(),
&name,
&tags,
&mut tag_name_to_id,
)
.await;
Self::update_description(id, description).await;
}
for resource in to_create {
let name = resource.name.clone();
let tags = resource.tags.clone();
let description = resource.description.clone();
let id = match Self::create(resource).await {
Ok(id) => id,
Err(e) => {
warn!(
"failed to create {} {name} | {e:#}",
Self::display(),
);
continue;
}
};
Self::update_tags(
id.clone(),
&name,
&tags,
&mut tag_name_to_id,
)
.await;
Self::update_description(id, description).await;
}
}
async fn update_tags(
resource_id: String,
resource_name: &str,
tags: &[String],
tag_name_to_id: &mut HashMap<String, String>,
) {
// make sure all tags are created
for tag_name in tags {
if !tag_name_to_id.contains_key(tag_name) {
let tag_id = monitor_client()
.write(CreateTag {
name: tag_name.to_string(),
})
.await
.expect("failed to CreateTag mid run")
.id;
tag_name_to_id.insert(tag_name.to_string(), tag_id);
}
}
// get Vec<tag_id>
let tags = tags
.iter()
.map(|tag_name| {
tag_name_to_id
.get(tag_name)
.expect("somehow didn't find tag at this point")
.to_string()
})
.collect();
// Update tags
if let Err(e) = monitor_client()
.write(UpdateTagsOnResource {
target: Self::resource_target(resource_id),
tags,
})
.await
{
warn!(
"failed to update tags on {} {resource_name} | {e:#}",
Self::display(),
);
}
}
async fn update_description(id: String, description: String) {
if let Err(e) = monitor_client()
.write(UpdateDescription {
target: Self::resource_target(id.clone()),
description,
})
.await
{
warn!("failed to update resource {id} description | {e:#}");
}
}
}
#[async_trait]
impl Sync for Server {
type ListItemInfo = ServerListItemInfo;
type PartialConfig = PartialServerConfig;
fn display() -> &'static str {
"server"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Server(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_server()
}
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String> {
monitor_client()
.write(write::CreateServer {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()> {
monitor_client()
.write(write::UpdateServer {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
#[async_trait]
impl Sync for Deployment {
type PartialConfig = PartialDeploymentConfig;
type ListItemInfo = DeploymentListItemInfo;
fn display() -> &'static str {
"deployment"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Deployment(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_deployment()
}
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String> {
monitor_client()
.write(write::CreateDeployment {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()> {
monitor_client()
.write(write::UpdateDeployment {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
#[async_trait]
impl Sync for Build {
type PartialConfig = PartialBuildConfig;
type ListItemInfo = BuildListItemInfo;
fn display() -> &'static str {
"build"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Build(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_build()
}
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String> {
monitor_client()
.write(write::CreateBuild {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()> {
monitor_client()
.write(write::UpdateBuild {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
#[async_trait]
impl Sync for Builder {
type PartialConfig = PartialBuilderConfig;
type ListItemInfo = BuilderListItemInfo;
fn display() -> &'static str {
"builder"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Builder(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_builder()
}
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String> {
monitor_client()
.write(write::CreateBuilder {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()> {
monitor_client()
.write(write::UpdateBuilder {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
#[async_trait]
impl Sync for Alerter {
type PartialConfig = PartialAlerterConfig;
type ListItemInfo = AlerterListItemInfo;
fn display() -> &'static str {
"alerter"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Alerter(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_alerter()
}
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String> {
monitor_client()
.write(write::CreateAlerter {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()> {
monitor_client()
.write(write::UpdateAlerter {
id,
config: resource.config,
})
.await?;
Ok(())
}
}
#[async_trait]
impl Sync for Repo {
type PartialConfig = PartialRepoConfig;
type ListItemInfo = RepoInfo;
fn display() -> &'static str {
"repo"
}
fn resource_target(id: String) -> ResourceTarget {
ResourceTarget::Repo(id)
}
fn name_to_resource(
) -> &'static HashMap<String, ResourceListItem<Self::ListItemInfo>>
{
name_to_repo()
}
async fn create(
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<String> {
monitor_client()
.write(write::CreateRepo {
name: resource.name,
config: resource.config,
})
.await
.map(|res| res.id)
}
async fn update(
id: String,
resource: Resource<Self::PartialConfig>,
) -> anyhow::Result<()> {
monitor_client()
.write(write::UpdateRepo {
id,
config: resource.config,
})
.await?;
Ok(())
}
}