user group sync

This commit is contained in:
mbecker20
2024-04-22 23:38:38 -07:00
parent f272612e74
commit de746096ab
7 changed files with 118 additions and 56 deletions

1
Cargo.lock generated
View File

@@ -2014,7 +2014,6 @@ dependencies = [
"opentelemetry-otlp",
"opentelemetry_sdk",
"serde",
"tokio",
"tracing",
"tracing-opentelemetry",
"tracing-subscriber",

View File

@@ -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(())
}

View File

@@ -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<Resource<PartialProcedureConfig>>,
#[serde(default, rename = "user_group")]
pub user_groups: Vec<UserGroup>,
pub user_groups: Vec<UserGroupToml>,
}
pub fn read_resources(path: &Path) -> anyhow::Result<ResourceFile> {

View File

@@ -20,7 +20,7 @@ pub mod server;
type ToUpdate<T> = Vec<(String, Resource<T>)>;
type ToCreate<T> = Vec<Resource<T>>;
type UpdatesResult<T> = (ToUpdate<T>, ToCreate<T>);
type UpdatesResult<T> = (ToCreate<T>, ToUpdate<T>);
pub trait ResourceSync {
type PartialConfig: Clone + Send + 'static;
@@ -45,7 +45,7 @@ pub trait ResourceSync {
fn get_updates(
resources: Vec<Resource<Self::PartialConfig>>,
) -> anyhow::Result<UpdatesResult<Self::PartialConfig>> {
) -> UpdatesResult<Self::PartialConfig> {
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<Self::PartialConfig>,
to_create: ToCreate<Self::PartialConfig>,
to_update: ToUpdate<Self::PartialConfig>,
) {
let log_after = !to_update.is_empty() || !to_create.is_empty();

View File

@@ -59,8 +59,8 @@ impl ResourceSync for Procedure {
}
async fn run_updates(
mut to_update: ToUpdate<Self::PartialConfig>,
mut to_create: ToCreate<Self::PartialConfig>,
mut to_update: ToUpdate<Self::PartialConfig>,
) {
if to_update.is_empty() && to_create.is_empty() {
return;

View File

@@ -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<UserGroupToml>) {
pub fn get_updates(
user_groups: Vec<UserGroupToml>,
) -> (Vec<UserGroupToml>, Vec<UserGroupToml>) {
let map = name_to_user_group();
let mut to_update = Vec::<UserGroupToUpdate>::new();
let mut to_create = Vec::<UserGroup>::new();
let mut to_create = Vec::<UserGroupToml>::new();
let mut to_update = Vec::<UserGroupToml>::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<UserGroupToml>) {
"\nUSER GROUPS TO UPDATE: {}",
to_update
.iter()
.map(|item| item.new.name.as_str())
.map(|item| item.name.as_str())
.collect::<Vec<_>>()
.join(", ")
);
}
(to_create, to_update)
}
async fn run_updates(
to_update: Vec<UserGroupToUpdate>,
to_create: Vec<UserGroup>,
pub async fn run_updates(
to_create: Vec<UserGroupToml>,
to_update: Vec<UserGroupToml>,
) {
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<String>) {
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<PermissionToml>,
) {
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:#}",
);
}
}
}

View File

@@ -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