Merge branch 'next' of https://github.com/mbecker20/monitor into next

This commit is contained in:
karamvir
2023-07-25 00:42:38 -07:00
12 changed files with 191 additions and 65 deletions

View File

@@ -17,14 +17,15 @@ use monitor_types::{
monitor_timestamp,
permissioned::Permissioned,
};
use mungos::{mongodb::bson::doc, AggStage::*};
use periphery_client::{requests, PeripheryClient};
use rand::{thread_rng, Rng};
use crate::{auth::RequestUser, state::State};
pub mod alert;
pub mod cache;
pub mod channel;
pub mod alert;
pub mod db;
pub fn empty_or_only_spaces(word: &str) -> bool {
@@ -59,7 +60,6 @@ pub fn make_update(
}
impl State {
// USER
pub async fn get_user(&self, user_id: &str) -> anyhow::Result<User> {
@@ -230,6 +230,34 @@ impl State {
Ok(build.get_user_permissions(user_id))
}
pub async fn get_build_ids_for_non_admin(&self, user_id: &str) -> anyhow::Result<Vec<String>> {
self.db
.builds
.aggregate_collect(
[
Match(doc! {
format!("permissions.{}", user_id): { "$in": ["update", "execute", "read"] }
}),
Project(doc! { "_id": 1 }),
],
None,
)
.await
.context("failed to get build ids for non admin | aggregation")?
.into_iter()
.map(|d| {
let id = d
.get("_id")
.context("no _id field")?
.as_object_id()
.context("_id not ObjectId")?
.to_string();
anyhow::Ok(id)
})
.collect::<anyhow::Result<Vec<_>>>()
.context("failed to get build ids for non admin | extract id from document")
}
// BUILDER
pub async fn get_builder(&self, builder_id: &str) -> anyhow::Result<Builder> {

View File

@@ -5,9 +5,9 @@ use monitor_types::{
build::{Build, BuildActionState},
PermissionLevel,
},
permissioned::Permissioned,
requests::read::*,
};
use mungos::mongodb::bson::doc;
use resolver_api::Resolve;
use crate::{auth::RequestUser, state::State};
@@ -27,6 +27,14 @@ impl Resolve<ListBuilds, RequestUser> for State {
ListBuilds { query }: ListBuilds,
user: RequestUser,
) -> anyhow::Result<Vec<BuildListItem>> {
let mut query = query.unwrap_or_default();
if !user.is_admin {
query.insert(
format!("permissions.{}", user.id),
doc! { "$in": ["read", "execute", "update"] },
);
}
let builds = self
.db
.builds
@@ -34,15 +42,6 @@ impl Resolve<ListBuilds, RequestUser> for State {
.await
.context("failed to pull builds from mongo")?;
let builds = if user.is_admin {
builds
} else {
builds
.into_iter()
.filter(|build| build.get_user_permissions(&user.id) > PermissionLevel::None)
.collect()
};
let builds = builds
.into_iter()
.map(|build| BuildListItem {
@@ -79,6 +78,24 @@ impl Resolve<GetBuildsSummary, RequestUser> for State {
GetBuildsSummary {}: GetBuildsSummary,
user: RequestUser,
) -> anyhow::Result<GetBuildsSummaryResponse> {
todo!()
let query = if user.is_admin {
None
} else {
let query = doc! {
format!("permissions.{}", user.id): { "$in": ["read", "execute", "update"] }
};
Some(query)
};
let total = self
.db
.builds
.collection
.count_documents(query, None)
.await
.context("failed to count all build documents")?;
let res = GetBuildsSummaryResponse {
total: total as u32,
};
Ok(res)
}
}

View File

@@ -2,9 +2,9 @@ use anyhow::Context;
use async_trait::async_trait;
use monitor_types::{
entities::{builder::Builder, PermissionLevel},
permissioned::Permissioned,
requests::read::*,
};
use mungos::mongodb::bson::doc;
use resolver_api::Resolve;
use crate::{auth::RequestUser, state::State};
@@ -28,6 +28,14 @@ impl Resolve<ListBuilders, RequestUser> for State {
ListBuilders { query }: ListBuilders,
user: RequestUser,
) -> anyhow::Result<Vec<Builder>> {
let mut query = query.unwrap_or_default();
if !user.is_admin {
query.insert(
format!("permissions.{}", user.id),
doc! { "$in": ["read", "execute", "update"] },
);
}
let builders = self
.db
.builders
@@ -35,15 +43,6 @@ impl Resolve<ListBuilders, RequestUser> for State {
.await
.context("failed to pull builders from mongo")?;
let builders = if user.is_admin {
builders
} else {
builders
.into_iter()
.filter(|builder| builder.get_user_permissions(&user.id) > PermissionLevel::None)
.collect()
};
Ok(builders)
}
}

View File

@@ -7,12 +7,11 @@ use monitor_types::{
entities::{
deployment::{
Deployment, DeploymentActionState, DeploymentConfig, DeploymentImage,
DockerContainerStats,
DockerContainerState, DockerContainerStats,
},
update::{Log, UpdateStatus},
Operation, PermissionLevel,
},
permissioned::Permissioned,
requests::read::*,
};
use mungos::mongodb::{bson::doc, options::FindOneOptions};
@@ -40,6 +39,13 @@ impl Resolve<ListDeployments, RequestUser> for State {
ListDeployments { query }: ListDeployments,
user: RequestUser,
) -> anyhow::Result<Vec<DeploymentListItem>> {
let mut query = query.unwrap_or_default();
if !user.is_admin {
query.insert(
format!("permissions.{}", user.id),
doc! { "$in": ["read", "execute", "update"] },
);
}
let deployments = self
.db
.deployments
@@ -47,17 +53,6 @@ impl Resolve<ListDeployments, RequestUser> for State {
.await
.context("failed to pull deployments from mongo")?;
let deployments = if user.is_admin {
deployments
} else {
deployments
.into_iter()
.filter(|deployment| {
deployment.get_user_permissions(&user.id) > PermissionLevel::None
})
.collect()
};
let deployments = deployments.into_iter().map(|deployment| async {
let status = self.deployment_status_cache.get(&deployment.id).await;
DeploymentListItem {
@@ -240,6 +235,43 @@ impl Resolve<GetDeploymentsSummary, RequestUser> for State {
GetDeploymentsSummary {}: GetDeploymentsSummary,
user: RequestUser,
) -> anyhow::Result<GetDeploymentsSummaryResponse> {
todo!()
let query = if user.is_admin {
None
} else {
let query = doc! {
format!("permissions.{}", user.id): { "$in": ["read", "execute", "update"] }
};
Some(query)
};
let deployments = self
.db
.deployments
.get_some(query, None)
.await
.context("failed to count all deployment documents")?;
let mut res = GetDeploymentsSummaryResponse::default();
for deployment in deployments {
res.total += 1;
let status = self
.deployment_status_cache
.get(&deployment.id)
.await
.unwrap_or_default();
match status.state {
DockerContainerState::Running => {
res.running += 1;
}
DockerContainerState::Unknown => {
res.unknown += 1;
}
DockerContainerState::NotDeployed => {
res.not_deployed += 1;
}
_ => {
res.stopped += 1;
}
}
}
Ok(res)
}
}

View File

@@ -5,9 +5,9 @@ use monitor_types::{
repo::{Repo, RepoActionState},
PermissionLevel,
},
permissioned::Permissioned,
requests::read::*,
};
use mungos::mongodb::bson::doc;
use resolver_api::Resolve;
use crate::{auth::RequestUser, state::State};
@@ -27,6 +27,14 @@ impl Resolve<ListRepos, RequestUser> for State {
ListRepos { query }: ListRepos,
user: RequestUser,
) -> anyhow::Result<Vec<RepoListItem>> {
let mut query = query.unwrap_or_default();
if !user.is_admin {
query.insert(
format!("permissions.{}", user.id),
doc! { "$in": ["read", "execute", "update"] },
);
}
let repos = self
.db
.repos
@@ -34,15 +42,6 @@ impl Resolve<ListRepos, RequestUser> for State {
.await
.context("failed to pull repos from mongo")?;
let repos = if user.is_admin {
repos
} else {
repos
.into_iter()
.filter(|repo| repo.get_user_permissions(&user.id) > PermissionLevel::None)
.collect()
};
let repos = repos
.into_iter()
.map(|repo| RepoListItem {

View File

@@ -6,13 +6,13 @@ use monitor_types::{
deployment::ContainerSummary,
server::{
docker_image::ImageSummary, docker_network::DockerNetwork, stats::SystemInformation,
Server, ServerActionState,
Server, ServerActionState, ServerStatus,
},
PermissionLevel,
},
permissioned::Permissioned,
requests::read::*,
};
use mungos::mongodb::bson::doc;
use periphery_client::requests;
use resolver_api::{Resolve, ResolveToString};
@@ -52,6 +52,14 @@ impl Resolve<ListServers, RequestUser> for State {
ListServers { query }: ListServers,
user: RequestUser,
) -> anyhow::Result<Vec<ServerListItem>> {
let mut query = query.unwrap_or_default();
if !user.is_admin {
query.insert(
format!("permissions.{}", user.id),
doc! { "$in": ["read", "execute", "update"] },
);
}
let servers = self
.db
.servers
@@ -59,15 +67,6 @@ impl Resolve<ListServers, RequestUser> for State {
.await
.context("failed to pull servers from mongo")?;
let servers = if user.is_admin {
servers
} else {
servers
.into_iter()
.filter(|server| server.get_user_permissions(&user.id) > PermissionLevel::None)
.collect()
};
let servers = servers.into_iter().map(|server| async {
let status = self.server_status_cache.get(&server.id).await;
ServerListItem {
@@ -351,6 +350,40 @@ impl Resolve<GetServersSummary, RequestUser> for State {
GetServersSummary {}: GetServersSummary,
user: RequestUser,
) -> anyhow::Result<GetServersSummaryResponse> {
todo!()
let query = if user.is_admin {
None
} else {
let query = doc! {
format!("permissions.{}", user.id): { "$in": ["read", "execute", "update"] }
};
Some(query)
};
let servers = self
.db
.servers
.get_some(query, None)
.await
.context("failed to get servers from db")?;
let mut res = GetServersSummaryResponse::default();
for server in servers {
res.total += 1;
let status = self
.server_status_cache
.get(&server.id)
.await
.unwrap_or_default();
match status.status {
ServerStatus::Ok => {
res.healthy += 1;
}
ServerStatus::NotOk => {
res.unhealthy += 1;
}
ServerStatus::Disabled => {
res.disabled += 1;
}
}
}
Ok(res)
}
}

View File

@@ -1,5 +1,6 @@
use async_trait::async_trait;
use monitor_types::{entities::update::Update, requests::read::ListUpdates};
use mungos::mongodb::{bson::doc, options::FindOptions};
use resolver_api::Resolve;
use crate::{auth::RequestUser, state::State};
@@ -11,7 +12,19 @@ impl Resolve<ListUpdates, RequestUser> for State {
ListUpdates { query }: ListUpdates,
user: RequestUser,
) -> anyhow::Result<Vec<Update>> {
todo!()
if user.is_admin {
let updates = self
.db
.updates
.get_some(
query,
FindOptions::builder().sort(doc! { "ts": -1 }).build(),
)
.await?;
Ok(updates)
} else {
let build_ids = self.get_build_ids_for_non_admin(&user.id).await?;
todo!()
}
}
}

View File

@@ -749,7 +749,7 @@ export interface GetBuildsSummary {
}
export interface GetBuildsSummaryResponse {
total: I64;
total: number;
}
export interface GetBuilder {
@@ -822,6 +822,7 @@ export interface GetDeploymentsSummaryResponse {
total: I64;
running: I64;
stopped: I64;
not_deployed: I64;
unknown: I64;
}
@@ -974,6 +975,7 @@ export interface GetServersSummaryResponse {
total: I64;
healthy: I64;
unhealthy: I64;
disabled: I64;
}
export interface GetTag {

View File

@@ -58,3 +58,4 @@ pub fn derive_crud_requests(input: proc_macro::TokenStream) -> proc_macro::Token
}
.into()
}

View File

@@ -57,5 +57,5 @@ pub struct GetBuildsSummary {}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GetBuildsSummaryResponse {
pub total: I64,
pub total: u32,
}

View File

@@ -114,10 +114,11 @@ pub struct GetDeploymentActionState {
pub struct GetDeploymentsSummary {}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct GetDeploymentsSummaryResponse {
pub total: I64,
pub running: I64,
pub stopped: I64,
pub not_deployed: I64,
pub unknown: I64,
}

View File

@@ -191,9 +191,10 @@ pub struct GetDockerContainers {
pub struct GetServersSummary {}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct GetServersSummaryResponse {
pub total: I64,
pub healthy: I64,
pub unhealthy: I64,
pub disabled: I64,
}