From de746096ab1a9cd1d6cb0055e9d27a953e070f00 Mon Sep 17 00:00:00 2001 From: mbecker20 Date: Mon, 22 Apr 2024 23:38:38 -0700 Subject: [PATCH] user group sync --- Cargo.lock | 1 - bin/monrun/src/sync/mod.rs | 46 +++++---- bin/monrun/src/sync/resource_file.rs | 5 +- bin/monrun/src/sync/resources/mod.rs | 8 +- bin/monrun/src/sync/resources/procedure.rs | 2 +- bin/monrun/src/sync/user_group.rs | 111 ++++++++++++++++----- lib/logger/Cargo.toml | 1 - 7 files changed, 118 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58e1a78c7..ddbb5e7f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2014,7 +2014,6 @@ dependencies = [ "opentelemetry-otlp", "opentelemetry_sdk", "serde", - "tokio", "tracing", "tracing-opentelemetry", "tracing-subscriber", diff --git a/bin/monrun/src/sync/mod.rs b/bin/monrun/src/sync/mod.rs index ee7c1c768..a601e6aed 100644 --- a/bin/monrun/src/sync/mod.rs +++ b/bin/monrun/src/sync/mod.rs @@ -19,40 +19,44 @@ pub async fn run_sync(path: &Path) -> anyhow::Result<()> { println!("{resources:#?}"); - let (server_updates, server_creates) = - Server::get_updates(resources.servers)?; - let (deployment_updates, deployment_creates) = - Deployment::get_updates(resources.deployments)?; - let (build_updates, build_creates) = - Build::get_updates(resources.builds)?; - let (builder_updates, builder_creates) = - Builder::get_updates(resources.builders)?; - let (alerter_updates, alerter_creates) = - Alerter::get_updates(resources.alerters)?; - let (repo_updates, repo_creates) = - Repo::get_updates(resources.repos)?; - let (procedure_updates, procedure_creates) = - Procedure::get_updates(resources.procedures)?; + let (server_creates, server_updates) = + Server::get_updates(resources.servers); + let (deployment_creates, deployment_updates) = + Deployment::get_updates(resources.deployments); + let (build_creates, build_updates) = + Build::get_updates(resources.builds); + let (builder_creates, builder_updates) = + Builder::get_updates(resources.builders); + let (alerter_creates, alerter_updates) = + Alerter::get_updates(resources.alerters); + let (repo_creates, repo_updates) = + Repo::get_updates(resources.repos); + let (procedure_creates, procedure_updates) = + Procedure::get_updates(resources.procedures); + let (user_group_creates, user_group_updates) = + user_group::get_updates(resources.user_groups); wait_for_enter("CONTINUE")?; // No deps - Server::run_updates(server_updates, server_creates).await; - Alerter::run_updates(alerter_updates, alerter_creates).await; + Server::run_updates(server_creates, server_updates).await; + Alerter::run_updates(alerter_creates, alerter_updates).await; // Dependant on server - Builder::run_updates(builder_updates, builder_creates).await; - Repo::run_updates(repo_updates, repo_creates).await; + Builder::run_updates(builder_creates, builder_updates).await; + Repo::run_updates(repo_creates, repo_updates).await; // Dependant on builder - Build::run_updates(build_updates, build_creates).await; + Build::run_updates(build_creates, build_updates).await; // Dependant on server / builder - Deployment::run_updates(deployment_updates, deployment_creates) + Deployment::run_updates(deployment_creates, deployment_updates) .await; // Dependant on everything - Procedure::run_updates(procedure_updates, procedure_creates).await; + Procedure::run_updates(procedure_creates, procedure_updates).await; + user_group::run_updates(user_group_creates, user_group_updates) + .await; Ok(()) } diff --git a/bin/monrun/src/sync/resource_file.rs b/bin/monrun/src/sync/resource_file.rs index 1e1995965..5b416944e 100644 --- a/bin/monrun/src/sync/resource_file.rs +++ b/bin/monrun/src/sync/resource_file.rs @@ -6,10 +6,11 @@ use monitor_client::entities::{ builder::PartialBuilderConfig, deployment::PartialDeploymentConfig, procedure::PartialProcedureConfig, repo::PartialRepoConfig, resource::Resource, server::PartialServerConfig, - user_group::UserGroup, }; use serde::Deserialize; +use super::user_group::UserGroupToml; + /// Specifies resources to sync on monitor #[derive(Debug, Clone, Default, Deserialize)] pub struct ResourceFile { @@ -35,7 +36,7 @@ pub struct ResourceFile { pub procedures: Vec>, #[serde(default, rename = "user_group")] - pub user_groups: Vec, + pub user_groups: Vec, } pub fn read_resources(path: &Path) -> anyhow::Result { diff --git a/bin/monrun/src/sync/resources/mod.rs b/bin/monrun/src/sync/resources/mod.rs index 91e1685ca..a30526c13 100644 --- a/bin/monrun/src/sync/resources/mod.rs +++ b/bin/monrun/src/sync/resources/mod.rs @@ -20,7 +20,7 @@ pub mod server; type ToUpdate = Vec<(String, Resource)>; type ToCreate = Vec>; -type UpdatesResult = (ToUpdate, ToCreate); +type UpdatesResult = (ToCreate, ToUpdate); pub trait ResourceSync { type PartialConfig: Clone + Send + 'static; @@ -45,7 +45,7 @@ pub trait ResourceSync { fn get_updates( resources: Vec>, - ) -> anyhow::Result> { + ) -> UpdatesResult { let map = Self::name_to_resource(); // (name, partial config) @@ -88,12 +88,12 @@ pub trait ResourceSync { ); } - Ok((to_update, to_create)) + (to_create, to_update) } async fn run_updates( - to_update: ToUpdate, to_create: ToCreate, + to_update: ToUpdate, ) { let log_after = !to_update.is_empty() || !to_create.is_empty(); diff --git a/bin/monrun/src/sync/resources/procedure.rs b/bin/monrun/src/sync/resources/procedure.rs index c6f74dd7f..0289394d9 100644 --- a/bin/monrun/src/sync/resources/procedure.rs +++ b/bin/monrun/src/sync/resources/procedure.rs @@ -59,8 +59,8 @@ impl ResourceSync for Procedure { } async fn run_updates( - mut to_update: ToUpdate, mut to_create: ToCreate, + mut to_update: ToUpdate, ) { if to_update.is_empty() && to_create.is_empty() { return; diff --git a/bin/monrun/src/sync/user_group.rs b/bin/monrun/src/sync/user_group.rs index 36345a634..d524adfc4 100644 --- a/bin/monrun/src/sync/user_group.rs +++ b/bin/monrun/src/sync/user_group.rs @@ -1,10 +1,15 @@ -use monitor_client::entities::{ - permission::PermissionLevel, update::ResourceTarget, - user_group::UserGroup, +use monitor_client::{ + api::write::{ + CreateUserGroup, SetUsersInUserGroup, UpdatePermissionOnTarget, + }, + entities::{ + permission::{PermissionLevel, UserTarget}, + update::ResourceTarget, + }, }; use serde::Deserialize; -use crate::maps::name_to_user_group; +use crate::{maps::name_to_user_group, monitor_client}; #[derive(Debug, Clone, Deserialize)] pub struct UserGroupToml { @@ -23,25 +28,19 @@ pub struct PermissionToml { pub level: PermissionLevel, } -struct UserGroupToUpdate { - pub old: UserGroup, - pub new: UserGroupToml, -} - -async fn get_updates(user_groups: Vec) { +pub fn get_updates( + user_groups: Vec, +) -> (Vec, Vec) { let map = name_to_user_group(); - let mut to_update = Vec::::new(); - let mut to_create = Vec::::new(); + let mut to_create = Vec::::new(); + let mut to_update = Vec::::new(); for user_group in user_groups { - // match map.get(&user_group.name).cloned() { - // Some(old) => to_update.push(UserGroupToUpdate { - // old, - // new: user_group, - // }), - // None => to_create.push(user_group), - // } + match map.get(&user_group.name).cloned() { + Some(_) => to_update.push(user_group), + None => to_create.push(user_group), + } } if !to_create.is_empty() { @@ -60,22 +59,82 @@ async fn get_updates(user_groups: Vec) { "\nUSER GROUPS TO UPDATE: {}", to_update .iter() - .map(|item| item.new.name.as_str()) + .map(|item| item.name.as_str()) .collect::>() .join(", ") ); } + + (to_create, to_update) } -async fn run_updates( - to_update: Vec, - to_create: Vec, +pub async fn run_updates( + to_create: Vec, + to_update: Vec, ) { let log_after = !to_update.is_empty() || !to_create.is_empty(); - for user_group in to_create {} + // Create the non-existant user groups + for user_group in to_create { + // Create the user group + if let Err(e) = monitor_client() + .write(CreateUserGroup { + name: user_group.name.clone(), + }) + .await + { + warn!( + "failed to create user group {} | {e:#}", + user_group.name + ); + continue; + }; - for UserGroupToUpdate { old, new } in to_update { - // + set_users(user_group.name.clone(), user_group.users).await; + update_permissions(user_group.name, user_group.permissions).await; + } + + // Update the existing user groups + for user_group in to_update { + set_users(user_group.name.clone(), user_group.users).await; + update_permissions(user_group.name, user_group.permissions).await; + } + + if log_after { + info!("============ user groups synced ✅ ============"); + } +} + +async fn set_users(user_group: String, users: Vec) { + if !users.is_empty() { + if let Err(e) = monitor_client() + .write(SetUsersInUserGroup { + user_group: user_group.clone(), + users, + }) + .await + { + warn!("failed to set users in group {user_group} | {e:#}"); + } + } +} + +async fn update_permissions( + user_group: String, + permissions: Vec, +) { + for PermissionToml { target, level } in permissions { + if let Err(e) = monitor_client() + .write(UpdatePermissionOnTarget { + user_target: UserTarget::UserGroup(user_group.clone()), + resource_target: target.clone(), + permission: level, + }) + .await + { + warn!( + "failed to set permssion in group {user_group} | target: {target:?} | {e:#}", + ); + } } } diff --git a/lib/logger/Cargo.toml b/lib/logger/Cargo.toml index 6692c1139..8d3ed0203 100644 --- a/lib/logger/Cargo.toml +++ b/lib/logger/Cargo.toml @@ -8,7 +8,6 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio.workspace = true serde.workspace = true anyhow.workspace = true tracing.workspace = true