mirror of
https://github.com/moghtech/komodo.git
synced 2026-04-28 03:38:55 -05:00
monrun diffing
This commit is contained in:
@@ -6,7 +6,7 @@ use monitor_client::{
|
||||
alerter::AlerterListItem, build::BuildListItem,
|
||||
builder::BuilderListItem, deployment::DeploymentListItem,
|
||||
procedure::ProcedureListItem, repo::RepoListItem,
|
||||
server::ServerListItem, user_group::UserGroup,
|
||||
server::ServerListItem, user::User, user_group::UserGroup,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -144,6 +144,20 @@ pub fn name_to_alerter() -> &'static HashMap<String, AlerterListItem>
|
||||
})
|
||||
}
|
||||
|
||||
pub fn id_to_alerter() -> &'static HashMap<String, AlerterListItem> {
|
||||
static ID_TO_ALERTER: OnceLock<HashMap<String, AlerterListItem>> =
|
||||
OnceLock::new();
|
||||
ID_TO_ALERTER.get_or_init(|| {
|
||||
futures::executor::block_on(
|
||||
monitor_client().read(read::ListAlerters::default()),
|
||||
)
|
||||
.expect("failed to get alerters from monitor")
|
||||
.into_iter()
|
||||
.map(|alerter| (alerter.id.clone(), alerter))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn name_to_repo() -> &'static HashMap<String, RepoListItem> {
|
||||
static NAME_TO_ALERTER: OnceLock<HashMap<String, RepoListItem>> =
|
||||
OnceLock::new();
|
||||
@@ -217,3 +231,17 @@ pub fn name_to_user_group() -> &'static HashMap<String, UserGroup> {
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn id_to_user() -> &'static HashMap<String, User> {
|
||||
static ID_TO_USER: OnceLock<HashMap<String, User>> =
|
||||
OnceLock::new();
|
||||
ID_TO_USER.get_or_init(|| {
|
||||
futures::executor::block_on(
|
||||
monitor_client().read(read::ListUsers::default()),
|
||||
)
|
||||
.expect("failed to get procedures from monitor")
|
||||
.into_iter()
|
||||
.map(|user| (user.id.clone(), user))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ pub async fn run_sync(path: &Path) -> anyhow::Result<()> {
|
||||
let (procedure_creates, procedure_updates) =
|
||||
Procedure::get_updates(resources.procedures).await?;
|
||||
let (user_group_creates, user_group_updates) =
|
||||
user_group::get_updates(resources.user_groups);
|
||||
user_group::get_updates(resources.user_groups).await?;
|
||||
|
||||
wait_for_enter("CONTINUE")?;
|
||||
|
||||
|
||||
@@ -1,26 +1,124 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use anyhow::Context;
|
||||
use monitor_client::{
|
||||
api::write::{
|
||||
CreateUserGroup, SetUsersInUserGroup, UpdatePermissionOnTarget,
|
||||
api::{
|
||||
read::ListUserTargetPermissions,
|
||||
write::{
|
||||
CreateUserGroup, SetUsersInUserGroup, UpdatePermissionOnTarget,
|
||||
},
|
||||
},
|
||||
entities::{
|
||||
permission::UserTarget,
|
||||
toml::{PermissionToml, UserGroupToml},
|
||||
update::ResourceTarget,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{maps::name_to_user_group, monitor_client};
|
||||
use crate::{
|
||||
maps::{
|
||||
id_to_alerter, id_to_build, id_to_builder, id_to_deployment,
|
||||
id_to_procedure, id_to_repo, id_to_server, id_to_user,
|
||||
name_to_user_group,
|
||||
},
|
||||
monitor_client,
|
||||
};
|
||||
|
||||
pub fn get_updates(
|
||||
pub async fn get_updates(
|
||||
user_groups: Vec<UserGroupToml>,
|
||||
) -> (Vec<UserGroupToml>, Vec<UserGroupToml>) {
|
||||
) -> anyhow::Result<(Vec<UserGroupToml>, Vec<UserGroupToml>)> {
|
||||
let map = name_to_user_group();
|
||||
|
||||
let mut to_create = Vec::<UserGroupToml>::new();
|
||||
let mut to_update = Vec::<UserGroupToml>::new();
|
||||
|
||||
for user_group in user_groups {
|
||||
for mut user_group in user_groups {
|
||||
match map.get(&user_group.name).cloned() {
|
||||
Some(_) => to_update.push(user_group),
|
||||
Some(original) => {
|
||||
// replace the user ids with usernames
|
||||
let mut users = original
|
||||
.users
|
||||
.into_iter()
|
||||
.filter_map(|user_id| {
|
||||
id_to_user().get(&user_id).map(|u| u.username.clone())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut permissions = monitor_client()
|
||||
.read(ListUserTargetPermissions {
|
||||
user_target: UserTarget::UserGroup(original.id),
|
||||
})
|
||||
.await
|
||||
.context("failed to query for UserGroup permissions")?
|
||||
.into_iter()
|
||||
.map(|mut p| {
|
||||
// replace the ids with names
|
||||
match &mut p.resource_target {
|
||||
ResourceTarget::System(_) => {}
|
||||
ResourceTarget::Build(id) => {
|
||||
*id = id_to_build()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
ResourceTarget::Builder(id) => {
|
||||
*id = id_to_builder()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
ResourceTarget::Deployment(id) => {
|
||||
*id = id_to_deployment()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
ResourceTarget::Server(id) => {
|
||||
*id = id_to_server()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
ResourceTarget::Repo(id) => {
|
||||
*id = id_to_repo()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
ResourceTarget::Alerter(id) => {
|
||||
*id = id_to_alerter()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
ResourceTarget::Procedure(id) => {
|
||||
*id = id_to_procedure()
|
||||
.get(id)
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
PermissionToml {
|
||||
target: p.resource_target,
|
||||
level: p.level,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
users.sort();
|
||||
user_group.users.sort();
|
||||
|
||||
user_group.permissions.sort_by(sort_permissions);
|
||||
permissions.sort_by(sort_permissions);
|
||||
|
||||
// only push update after failed diff
|
||||
if user_group.users != users
|
||||
|| user_group.permissions != permissions
|
||||
{
|
||||
// no update from users
|
||||
to_update.push(user_group);
|
||||
}
|
||||
}
|
||||
None => to_create.push(user_group),
|
||||
}
|
||||
}
|
||||
@@ -47,7 +145,23 @@ pub fn get_updates(
|
||||
);
|
||||
}
|
||||
|
||||
(to_create, to_update)
|
||||
Ok((to_create, to_update))
|
||||
}
|
||||
|
||||
/// order permissions in deterministic way
|
||||
fn sort_permissions(
|
||||
a: &PermissionToml,
|
||||
b: &PermissionToml,
|
||||
) -> Ordering {
|
||||
let (a_t, a_id) = a.target.extract_variant_id();
|
||||
let (b_t, b_id) = b.target.extract_variant_id();
|
||||
match (a_t.cmp(&b_t), a_id.cmp(b_id)) {
|
||||
(Ordering::Greater, _) => Ordering::Greater,
|
||||
(Ordering::Less, _) => Ordering::Less,
|
||||
(_, Ordering::Greater) => Ordering::Greater,
|
||||
(_, Ordering::Less) => Ordering::Less,
|
||||
_ => Ordering::Equal,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run_updates(
|
||||
|
||||
@@ -47,7 +47,7 @@ pub type ListApiKeysForServiceUserResponse = Vec<ApiKey>;
|
||||
/// Response: [ListUsersResponse]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Request, EmptyTraits,
|
||||
Serialize, Deserialize, Debug, Clone, Default, Request, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(MonitorReadRequest)]
|
||||
#[response(ListUsersResponse)]
|
||||
|
||||
@@ -97,7 +97,7 @@ pub struct UserGroupToml {
|
||||
pub permissions: Vec<PermissionToml>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct PermissionToml {
|
||||
pub target: ResourceTarget,
|
||||
pub level: PermissionLevel,
|
||||
|
||||
@@ -152,11 +152,13 @@ impl Log {
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Display,
|
||||
EnumString,
|
||||
AsRefStr,
|
||||
PartialEq,
|
||||
Eq
|
||||
)]
|
||||
#[serde(tag = "type", content = "id")]
|
||||
pub enum ResourceTarget {
|
||||
|
||||
Reference in New Issue
Block a user