From d2a3a6cddffb516dbbfbc1dc26dad2f6f4944916 Mon Sep 17 00:00:00 2001 From: mbecker20 Date: Sun, 25 Dec 2022 05:46:21 +0000 Subject: [PATCH] refactor types lib into split files for easier finding of things --- lib/types/src/build.rs | 107 +++++ lib/types/src/config.rs | 95 ++++ lib/types/src/deployment.rs | 198 ++++++++ lib/types/src/diff.rs | 34 ++ lib/types/src/lib.rs | 872 +----------------------------------- lib/types/src/procedure.rs | 81 ++++ lib/types/src/server.rs | 167 +++++++ lib/types/src/update.rs | 147 ++++++ lib/types/src/user.rs | 70 +++ 9 files changed, 919 insertions(+), 852 deletions(-) create mode 100644 lib/types/src/build.rs create mode 100644 lib/types/src/config.rs create mode 100644 lib/types/src/deployment.rs create mode 100644 lib/types/src/diff.rs create mode 100644 lib/types/src/procedure.rs create mode 100644 lib/types/src/server.rs create mode 100644 lib/types/src/update.rs create mode 100644 lib/types/src/user.rs diff --git a/lib/types/src/build.rs b/lib/types/src/build.rs new file mode 100644 index 000000000..0125636f9 --- /dev/null +++ b/lib/types/src/build.rs @@ -0,0 +1,107 @@ +use bson::serde_helpers::hex_string_as_object_id; +use derive_builder::Builder; +use diff::Diff; +use serde::{Deserialize, Serialize}; +use typeshare::typeshare; + +use crate::{diff::*, Command, EnvironmentVar, PermissionsMap}; + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct Build { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + #[builder(setter(skip))] + pub id: String, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub name: String, + + #[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))] + #[builder(setter(skip))] + pub permissions: PermissionsMap, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub server_id: String, // server which this image should be built on + + pub version: Version, + + // git related + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub repo: Option, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub branch: Option, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub github_account: Option, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub on_clone: Option, + + // build related + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub pre_build: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub docker_build_args: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub docker_account: Option, + + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub created_at: String, + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub updated_at: String, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct BuildActionState { + pub building: bool, + pub recloning: bool, + pub updating: bool, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] +#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] +pub struct Version { + pub major: i32, + pub minor: i32, + pub patch: i32, +} + +impl ToString for Version { + fn to_string(&self) -> String { + format!("{}.{}.{}", self.major, self.minor, self.patch) + } +} + +impl Version { + pub fn increment(&mut self) { + self.patch += 1; + } +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, Diff, Builder)] +#[diff(attr(#[derive(Debug, Serialize, PartialEq)]))] +pub struct DockerBuildArgs { + pub build_path: String, + pub dockerfile_path: Option, + pub build_args: Vec, +} diff --git a/lib/types/src/config.rs b/lib/types/src/config.rs new file mode 100644 index 000000000..f54cd6599 --- /dev/null +++ b/lib/types/src/config.rs @@ -0,0 +1,95 @@ +use std::collections::HashMap; + +use async_timing_util::Timelength; +use serde::{Deserialize, Serialize}; + +pub type GithubUsername = String; +pub type GithubToken = String; +pub type GithubAccounts = HashMap; + +pub type DockerUsername = String; +pub type DockerToken = String; +pub type DockerAccounts = HashMap; + +pub type SecretsMap = HashMap; // these are used for injection into deployments run commands + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct CoreConfig { + // port the core web server runs on + #[serde(default = "default_core_port")] + pub port: u16, + + // jwt config + pub jwt_secret: String, + #[serde(default = "default_jwt_valid_for")] + pub jwt_valid_for: Timelength, + + // integration with slack app + pub slack_url: Option, + + // github integration + pub github_webhook_secret: String, + pub github_oauth: OauthCredentials, + + // mongo config + pub mongo: MongoConfig, +} + +fn default_core_port() -> u16 { + 9000 +} + +fn default_jwt_valid_for() -> Timelength { + Timelength::OneWeek +} + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct OauthCredentials { + pub id: String, + pub secret: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct MongoConfig { + pub uri: String, + #[serde(default = "default_core_mongo_app_name")] + pub app_name: String, + #[serde(default = "default_core_mongo_db_name")] + pub db_name: String, +} + +fn default_core_mongo_app_name() -> String { + "monitor_core".to_string() +} + +fn default_core_mongo_db_name() -> String { + "monitor".to_string() +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct PeripheryConfig { + #[serde(default = "default_periphery_port")] + pub port: u16, + #[serde(default = "default_repo_dir")] + pub repo_dir: String, + #[serde(default = "default_stats_refresh_interval")] + pub stats_polling_rate: Timelength, + #[serde(default)] + pub secrets: SecretsMap, + #[serde(default)] + pub github_accounts: GithubAccounts, + #[serde(default)] + pub docker_accounts: DockerAccounts, +} + +fn default_periphery_port() -> u16 { + 8000 +} + +fn default_repo_dir() -> String { + "/repos".to_string() +} + +fn default_stats_refresh_interval() -> Timelength { + Timelength::OneSecond +} diff --git a/lib/types/src/deployment.rs b/lib/types/src/deployment.rs new file mode 100644 index 000000000..1b4fa7cda --- /dev/null +++ b/lib/types/src/deployment.rs @@ -0,0 +1,198 @@ +use bson::serde_helpers::hex_string_as_object_id; +use derive_builder::Builder; +use diff::Diff; +use serde::{Deserialize, Serialize}; +use strum_macros::{Display, EnumString}; +use typeshare::typeshare; + +use crate::{diff::*, Command, EnvironmentVar, PermissionsMap, Version}; + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct Deployment { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + #[builder(setter(skip))] + pub id: String, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub name: String, // must be formatted to be compat with docker + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub server_id: String, + + #[serde(default)] + #[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))] + #[builder(setter(skip))] + pub permissions: PermissionsMap, + + #[diff(attr(#[serde(skip_serializing_if = "docker_run_args_diff_no_change")]))] + pub docker_run_args: DockerRunArgs, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub build_id: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub build_version: Option, + + // deployment repo related + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub repo: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub branch: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub github_account: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub on_clone: Option, + + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub created_at: String, + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub updated_at: String, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct DeploymentWithContainer { + pub deployment: Deployment, + pub container: Option, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct DeploymentActionState { + pub deploying: bool, + pub stopping: bool, + pub starting: bool, + pub removing: bool, + pub pulling: bool, + pub recloning: bool, + pub updating: bool, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] +#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] +pub struct DockerRunArgs { + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub image: String, + + #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] + pub ports: Vec, + + #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] + pub volumes: Vec, + + #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] + pub environment: Vec, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub network: Option, + + #[diff(attr(#[serde(skip_serializing_if = "restart_mode_diff_no_change")]))] + pub restart: RestartMode, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub post_image: Option, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub container_user: Option, + + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub docker_account: Option, // the username of the dockerhub account +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct BasicContainerInfo { + pub name: String, + pub id: String, + pub state: DockerContainerState, + pub status: Option, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] +#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] +pub struct Conversion { + pub local: String, + pub container: String, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct DockerContainerStats { + #[serde(alias = "Name")] + pub name: String, + #[serde(alias = "CPUPerc")] + pub cpu_perc: String, + #[serde(alias = "MemPerc")] + pub mem_perc: String, + #[serde(alias = "MemUsage")] + pub mem_usage: String, + #[serde(alias = "NetIO")] + pub net_io: String, + #[serde(alias = "BlockIO")] + pub block_io: String, + #[serde(alias = "PIDs")] + pub pids: String, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum DockerContainerState { + Created, + Restarting, + Running, + Removing, + Paused, + Exited, + Dead, +} + +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff, +)] +#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] +pub enum RestartMode { + #[serde(rename = "no")] + #[strum(serialize = "no")] + NoRestart, + #[serde(rename = "on-failure")] + #[strum(serialize = "on-failure")] + OnFailure, + #[serde(rename = "always")] + #[strum(serialize = "always")] + Always, + #[serde(rename = "unless-stopped")] + #[strum(serialize = "unless-stopped")] + UnlessStopped, +} + +impl Default for RestartMode { + fn default() -> RestartMode { + RestartMode::NoRestart + } +} diff --git a/lib/types/src/diff.rs b/lib/types/src/diff.rs new file mode 100644 index 000000000..80401350e --- /dev/null +++ b/lib/types/src/diff.rs @@ -0,0 +1,34 @@ +use diff::{Diff, HashMapDiff, OptionDiff, VecDiff}; + +use crate::deployment::{DockerRunArgsDiff, RestartModeDiff}; + +pub fn option_diff_no_change(option_diff: &OptionDiff) -> bool +where + ::Repr: PartialEq, +{ + option_diff == &OptionDiff::NoChange || option_diff == &OptionDiff::None +} + +pub fn vec_diff_no_change(vec_diff: &VecDiff) -> bool { + vec_diff.0.is_empty() +} + +pub fn hashmap_diff_no_change(hashmap_diff: &HashMapDiff) -> bool { + hashmap_diff.altered.is_empty() && hashmap_diff.removed.is_empty() +} + +pub fn docker_run_args_diff_no_change(dra: &DockerRunArgsDiff) -> bool { + dra.image.is_none() + && option_diff_no_change(&dra.container_user) + && option_diff_no_change(&dra.docker_account) + && option_diff_no_change(&dra.network) + && option_diff_no_change(&dra.post_image) + && vec_diff_no_change(&dra.environment) + && vec_diff_no_change(&dra.ports) + && vec_diff_no_change(&dra.volumes) + && restart_mode_diff_no_change(&dra.restart) +} + +pub fn restart_mode_diff_no_change(restart_mode: &RestartModeDiff) -> bool { + restart_mode == &RestartModeDiff::NoChange +} diff --git a/lib/types/src/lib.rs b/lib/types/src/lib.rs index 675b01d96..282c299f8 100644 --- a/lib/types/src/lib.rs +++ b/lib/types/src/lib.rs @@ -1,523 +1,38 @@ -use std::{collections::HashMap, path::PathBuf}; +use std::collections::HashMap; +use ::diff::Diff; use anyhow::Context; -use async_timing_util::Timelength; -use bson::serde_helpers::hex_string_as_object_id; use chrono::{DateTime, SecondsFormat, Utc}; -use derive_builder::Builder; -use diff::{Diff, HashMapDiff, OptionDiff, VecDiff}; use serde::{Deserialize, Serialize}; use strum_macros::{Display, EnumString}; +use typeshare::typeshare; pub use bollard::service::{ImageSummary, Network}; -use typeshare::typeshare; pub mod traits; +mod build; +mod config; +mod deployment; +mod diff; +mod procedure; +mod server; +mod update; +mod user; + +pub use build::*; +pub use config::*; +pub use deployment::*; +pub use procedure::*; +pub use server::*; +pub use update::*; +pub use user::*; + pub const PERIPHERY_BUILDER_BUSY: &str = "builder is busy"; -pub type GithubUsername = String; -pub type GithubToken = String; -pub type GithubAccounts = HashMap; - -pub type DockerUsername = String; -pub type DockerToken = String; -pub type DockerAccounts = HashMap; - -pub type SecretsMap = HashMap; // these are used for injection into deployments run commands - #[typeshare] pub type PermissionsMap = HashMap; -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct User { - #[serde( - default, - rename = "_id", - skip_serializing_if = "String::is_empty", - with = "hex_string_as_object_id" - )] - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub id: String, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub username: String, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub enabled: bool, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub admin: bool, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub create_server_permissions: bool, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub avatar: Option, - - // used with auth - #[serde(default)] - #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] - pub secrets: Vec, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub password: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub github_id: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub google_id: Option, - - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - pub created_at: String, - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - pub updated_at: String, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct ApiSecret { - pub name: String, - pub hash: String, - pub created_at: String, - pub expires: Option, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Diff, Builder)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct Server { - #[serde( - default, - rename = "_id", - skip_serializing_if = "String::is_empty", - with = "hex_string_as_object_id" - )] - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - #[builder(setter(skip))] - pub id: String, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub name: String, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub address: String, - - #[serde(default)] - #[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))] - #[builder(setter(skip))] - pub permissions: PermissionsMap, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub enabled: bool, - - #[serde(default)] - #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] - pub to_notify: Vec, // slack users to notify - - #[serde(default = "default_cpu_alert")] - pub cpu_alert: f64, - #[serde(default = "default_mem_alert")] - pub mem_alert: f64, - #[serde(default = "default_disk_alert")] - pub disk_alert: f64, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub stats_interval: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub region: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub instance_id: Option, - - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub created_at: String, - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub updated_at: String, -} - -impl Default for Server { - fn default() -> Self { - Self { - id: Default::default(), - name: Default::default(), - address: Default::default(), - permissions: Default::default(), - enabled: true, - to_notify: Default::default(), - cpu_alert: default_cpu_alert(), - mem_alert: default_mem_alert(), - disk_alert: default_disk_alert(), - stats_interval: Default::default(), - region: Default::default(), - instance_id: Default::default(), - created_at: Default::default(), - updated_at: Default::default(), - } - } -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ServerWithStatus { - pub server: Server, - pub status: ServerStatus, -} - -fn default_cpu_alert() -> f64 { - 50.0 -} - -fn default_mem_alert() -> f64 { - 75.0 -} - -fn default_disk_alert() -> f64 { - 75.0 -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct ServerActionState { - pub pruning_networks: bool, - pub pruning_containers: bool, - pub pruning_images: bool, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct Deployment { - #[serde( - default, - rename = "_id", - skip_serializing_if = "String::is_empty", - with = "hex_string_as_object_id" - )] - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - #[builder(setter(skip))] - pub id: String, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub name: String, // must be formatted to be compat with docker - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub server_id: String, - - #[serde(default)] - #[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))] - #[builder(setter(skip))] - pub permissions: PermissionsMap, - - #[diff(attr(#[serde(skip_serializing_if = "docker_run_args_diff_no_change")]))] - pub docker_run_args: DockerRunArgs, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub build_id: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub build_version: Option, - - // deployment repo related - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub repo: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub branch: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub github_account: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub on_clone: Option, - - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub created_at: String, - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub updated_at: String, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct DeploymentWithContainer { - pub deployment: Deployment, - pub container: Option, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct DeploymentActionState { - pub deploying: bool, - pub stopping: bool, - pub starting: bool, - pub removing: bool, - pub pulling: bool, - pub recloning: bool, - pub updating: bool, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct Build { - #[serde( - default, - rename = "_id", - skip_serializing_if = "String::is_empty", - with = "hex_string_as_object_id" - )] - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - #[builder(setter(skip))] - pub id: String, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub name: String, - - #[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))] - #[builder(setter(skip))] - pub permissions: PermissionsMap, - - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub server_id: String, // server which this image should be built on - - pub version: Version, - - // git related - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub repo: Option, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub branch: Option, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub github_account: Option, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub on_clone: Option, - - // build related - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub pre_build: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub docker_build_args: Option, - - #[serde(skip_serializing_if = "Option::is_none")] - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub docker_account: Option, - - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub created_at: String, - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub updated_at: String, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct BuildActionState { - pub building: bool, - pub recloning: bool, - pub updating: bool, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct Update { - #[serde( - default, - rename = "_id", - skip_serializing_if = "String::is_empty", - with = "hex_string_as_object_id" - )] - pub id: String, - pub target: UpdateTarget, - pub operation: Operation, - pub logs: Vec, - pub start_ts: String, - pub end_ts: Option, - pub status: UpdateStatus, - pub success: bool, - pub operator: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub version: Option, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct Procedure { - #[serde( - default, - rename = "_id", - skip_serializing_if = "String::is_empty", - with = "hex_string_as_object_id" - )] - #[builder(setter(skip))] - pub id: String, - pub name: String, - pub stages: Vec, - #[builder(setter(skip))] - pub permissions: PermissionsMap, - - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub created_at: String, - #[serde(default)] - #[diff(attr(#[serde(skip)]))] - #[builder(setter(skip))] - pub updated_at: String, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] -#[diff(attr(#[derive(Debug, Serialize)]))] -pub struct ProcedureStage { - pub operation: ProcedureOperation, - pub target_id: String, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, Diff, Builder)] -#[diff(attr(#[derive(Debug, Serialize, PartialEq)]))] -pub struct DockerBuildArgs { - pub build_path: String, - pub dockerfile_path: Option, - pub build_args: Vec, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] -#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] -pub struct DockerRunArgs { - #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] - pub image: String, - - #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] - pub ports: Vec, - - #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] - pub volumes: Vec, - - #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] - pub environment: Vec, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub network: Option, - - #[diff(attr(#[serde(skip_serializing_if = "restart_mode_diff_no_change")]))] - pub restart: RestartMode, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub post_image: Option, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub container_user: Option, - - #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] - pub docker_account: Option, // the username of the dockerhub account -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BasicContainerInfo { - pub name: String, - pub id: String, - pub state: DockerContainerState, - pub status: Option, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct DockerContainerStats { - #[serde(alias = "Name")] - pub name: String, - #[serde(alias = "CPUPerc")] - pub cpu_perc: String, - #[serde(alias = "MemPerc")] - pub mem_perc: String, - #[serde(alias = "MemUsage")] - pub mem_usage: String, - #[serde(alias = "NetIO")] - pub net_io: String, - #[serde(alias = "BlockIO")] - pub block_io: String, - #[serde(alias = "PIDs")] - pub pids: String, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct Log { - pub stage: String, - pub command: String, - pub stdout: String, - pub stderr: String, - pub success: bool, - pub start_ts: String, - pub end_ts: String, -} - -impl Log { - pub fn simple(stage: &str, msg: String) -> Log { - let ts = monitor_timestamp(); - Log { - stage: stage.to_string(), - stdout: msg, - success: true, - start_ts: ts.clone(), - end_ts: ts, - ..Default::default() - } - } - - pub fn error(stage: &str, msg: String) -> Log { - let ts = monitor_timestamp(); - Log { - stage: stage.to_string(), - stderr: msg, - start_ts: ts.clone(), - end_ts: ts, - success: false, - ..Default::default() - } - } -} - #[typeshare] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Diff)] #[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] @@ -526,35 +41,6 @@ pub struct Command { pub command: String, } -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] -#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] -pub struct Version { - pub major: i32, - pub minor: i32, - pub patch: i32, -} - -impl ToString for Version { - fn to_string(&self) -> String { - format!("{}.{}.{}", self.major, self.minor, self.patch) - } -} - -impl Version { - pub fn increment(&mut self) { - self.patch += 1; - } -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] -#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] -pub struct Conversion { - pub local: String, - pub container: String, -} - #[typeshare] #[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] #[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] @@ -563,87 +49,6 @@ pub struct EnvironmentVar { pub value: String, } -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct OauthCredentials { - pub id: String, - pub secret: String, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct CoreConfig { - // port the core web server runs on - #[serde(default = "default_core_port")] - pub port: u16, - - // jwt config - pub jwt_secret: String, - #[serde(default = "default_jwt_valid_for")] - pub jwt_valid_for: Timelength, - - // integration with slack app - pub slack_url: Option, - - // github integration - pub github_webhook_secret: String, - pub github_oauth: OauthCredentials, - - // mongo config - pub mongo: MongoConfig, -} - -fn default_core_port() -> u16 { - 9000 -} - -fn default_jwt_valid_for() -> Timelength { - Timelength::OneWeek -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct MongoConfig { - pub uri: String, - #[serde(default = "default_core_mongo_app_name")] - pub app_name: String, - #[serde(default = "default_core_mongo_db_name")] - pub db_name: String, -} - -fn default_core_mongo_app_name() -> String { - "monitor_core".to_string() -} - -fn default_core_mongo_db_name() -> String { - "monitor".to_string() -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct PeripheryConfig { - #[serde(default = "default_periphery_port")] - pub port: u16, - #[serde(default = "default_repo_dir")] - pub repo_dir: String, - #[serde(default = "default_stats_refresh_interval")] - pub stats_polling_rate: Timelength, - #[serde(default)] - pub secrets: SecretsMap, - #[serde(default)] - pub github_accounts: GithubAccounts, - #[serde(default)] - pub docker_accounts: DockerAccounts, -} - -fn default_periphery_port() -> u16 { - 8000 -} - -fn default_repo_dir() -> String { - "/repos".to_string() -} - -fn default_stats_refresh_interval() -> Timelength { - Timelength::OneSecond -} - #[typeshare] #[derive(Deserialize, Debug)] pub struct UserCredentials { @@ -651,43 +56,6 @@ pub struct UserCredentials { pub password: String, } -#[typeshare] -#[derive(Serialize, Deserialize, Debug)] -pub struct SystemStats { - pub cpu_perc: f32, // in % - pub mem_used_gb: f64, // in GB - pub mem_total_gb: f64, // in GB - pub disk: DiskUsage, - pub networks: Vec, - pub polling_rate: Timelength, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug)] -pub struct DiskUsage { - pub used_gb: f64, // in GB - pub total_gb: f64, // in GB - pub read_kb: f64, // in kB - pub write_kb: f64, // in kB - pub disks: Vec, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug)] -pub struct SingleDiskUsage { - pub mount: PathBuf, - pub used_gb: f64, // in GB - pub total_gb: f64, // in GB -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug)] -pub struct SystemNetwork { - pub name: String, - pub recieved_kb: f64, // in kB - pub transmitted_kb: f64, // in kB -} - #[typeshare] #[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] #[serde(rename_all = "snake_case")] @@ -697,87 +65,6 @@ pub enum AccountType { Docker, } -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(tag = "type", content = "id")] -pub enum UpdateTarget { - System, - Build(String), - Deployment(String), - Server(String), - Procedure(String), -} - -impl Default for UpdateTarget { - fn default() -> Self { - UpdateTarget::System - } -} - -impl From<&Build> for UpdateTarget { - fn from(build: &Build) -> Self { - Self::Build(build.id.clone()) - } -} - -impl From<&Build> for Option { - fn from(build: &Build) -> Self { - Some(UpdateTarget::Build(build.id.clone())) - } -} - -impl From<&Deployment> for UpdateTarget { - fn from(deployment: &Deployment) -> Self { - Self::Deployment(deployment.id.clone()) - } -} - -impl From<&Deployment> for Option { - fn from(deployment: &Deployment) -> Self { - Some(UpdateTarget::Deployment(deployment.id.clone())) - } -} - -impl From<&Server> for UpdateTarget { - fn from(server: &Server) -> Self { - Self::Server(server.id.clone()) - } -} - -impl From<&Server> for Option { - fn from(server: &Server) -> Self { - Some(UpdateTarget::Server(server.id.clone())) - } -} - -impl From<&Procedure> for UpdateTarget { - fn from(procedure: &Procedure) -> Self { - Self::Procedure(procedure.id.clone()) - } -} - -impl From<&Procedure> for Option { - fn from(procedure: &Procedure) -> Self { - Some(UpdateTarget::Procedure(procedure.id.clone())) - } -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum UpdateStatus { - Queued, - InProgress, - Complete, -} - -impl Default for UpdateStatus { - fn default() -> Self { - UpdateStatus::Complete - } -} - #[typeshare] #[derive( Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff, @@ -831,44 +118,6 @@ impl Default for Operation { } } -#[typeshare] -#[derive( - Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff, -)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] -pub enum ProcedureOperation { - // do nothing - None, - - // server - PruneImagesServer, - PruneContainersServer, - PruneNetworksServer, - - // build - BuildBuild, - RecloneBuild, - - // deployment - DeployContainer, - StopContainer, - StartContainer, - RemoveContainer, - PullDeployment, - RecloneDeployment, - - // procedure - RunProcedure, -} - -impl Default for ProcedureOperation { - fn default() -> Self { - ProcedureOperation::None - } -} - #[typeshare] #[derive( Serialize, @@ -918,87 +167,6 @@ pub enum PermissionsTarget { Procedure, } -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum ServerStatus { - Ok, - NotOk, - Disabled, -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum DockerContainerState { - Created, - Restarting, - Running, - Removing, - Paused, - Exited, - Dead, -} - -#[typeshare] -#[derive( - Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff, -)] -#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] -pub enum RestartMode { - #[serde(rename = "no")] - #[strum(serialize = "no")] - NoRestart, - #[serde(rename = "on-failure")] - #[strum(serialize = "on-failure")] - OnFailure, - #[serde(rename = "always")] - #[strum(serialize = "always")] - Always, - #[serde(rename = "unless-stopped")] - #[strum(serialize = "unless-stopped")] - UnlessStopped, -} - -impl Default for RestartMode { - fn default() -> RestartMode { - RestartMode::NoRestart - } -} - -fn option_diff_no_change(option_diff: &OptionDiff) -> bool -where - ::Repr: PartialEq, -{ - option_diff == &OptionDiff::NoChange || option_diff == &OptionDiff::None -} - -fn vec_diff_no_change(vec_diff: &VecDiff) -> bool { - vec_diff.0.is_empty() -} - -fn hashmap_diff_no_change(hashmap_diff: &HashMapDiff) -> bool { - hashmap_diff.altered.is_empty() && hashmap_diff.removed.is_empty() -} - -fn docker_run_args_diff_no_change(dra: &DockerRunArgsDiff) -> bool { - dra.image.is_none() - && option_diff_no_change(&dra.container_user) - && option_diff_no_change(&dra.docker_account) - && option_diff_no_change(&dra.network) - && option_diff_no_change(&dra.post_image) - && vec_diff_no_change(&dra.environment) - && vec_diff_no_change(&dra.ports) - && vec_diff_no_change(&dra.volumes) - && restart_mode_diff_no_change(&dra.restart) -} - -fn restart_mode_diff_no_change(restart_mode: &RestartModeDiff) -> bool { - restart_mode == &RestartModeDiff::NoChange -} - pub fn monitor_timestamp() -> String { Utc::now().to_rfc3339_opts(SecondsFormat::Millis, false) } diff --git a/lib/types/src/procedure.rs b/lib/types/src/procedure.rs new file mode 100644 index 000000000..cdaacb8fd --- /dev/null +++ b/lib/types/src/procedure.rs @@ -0,0 +1,81 @@ +use bson::serde_helpers::hex_string_as_object_id; +use derive_builder::Builder; +use diff::Diff; +use serde::{Deserialize, Serialize}; +use strum_macros::{Display, EnumString}; +use typeshare::typeshare; + +use crate::PermissionsMap; + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct Procedure { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + #[builder(setter(skip))] + pub id: String, + pub name: String, + pub stages: Vec, + #[builder(setter(skip))] + pub permissions: PermissionsMap, + + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub created_at: String, + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub updated_at: String, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct ProcedureStage { + pub operation: ProcedureOperation, + pub target_id: String, +} + +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff, +)] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))] +pub enum ProcedureOperation { + // do nothing + None, + + // server + PruneImagesServer, + PruneContainersServer, + PruneNetworksServer, + + // build + BuildBuild, + RecloneBuild, + + // deployment + DeployContainer, + StopContainer, + StartContainer, + RemoveContainer, + PullDeployment, + RecloneDeployment, + + // procedure + RunProcedure, +} + +impl Default for ProcedureOperation { + fn default() -> Self { + ProcedureOperation::None + } +} diff --git a/lib/types/src/server.rs b/lib/types/src/server.rs new file mode 100644 index 000000000..93a8b930a --- /dev/null +++ b/lib/types/src/server.rs @@ -0,0 +1,167 @@ +use std::path::PathBuf; + +use async_timing_util::Timelength; +use bson::serde_helpers::hex_string_as_object_id; +use derive_builder::Builder; +use diff::Diff; +use serde::{Deserialize, Serialize}; +use strum_macros::{Display, EnumString}; +use typeshare::typeshare; + +use crate::{diff::*, PermissionsMap}; + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Diff, Builder)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct Server { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + #[builder(setter(skip))] + pub id: String, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub name: String, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub address: String, + + #[serde(default)] + #[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))] + #[builder(setter(skip))] + pub permissions: PermissionsMap, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub enabled: bool, + + #[serde(default)] + #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] + pub to_notify: Vec, // slack users to notify + + #[serde(default = "default_cpu_alert")] + pub cpu_alert: f64, + #[serde(default = "default_mem_alert")] + pub mem_alert: f64, + #[serde(default = "default_disk_alert")] + pub disk_alert: f64, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub stats_interval: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub region: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub instance_id: Option, + + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub created_at: String, + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + #[builder(setter(skip))] + pub updated_at: String, +} + +impl Default for Server { + fn default() -> Self { + Self { + id: Default::default(), + name: Default::default(), + address: Default::default(), + permissions: Default::default(), + enabled: true, + to_notify: Default::default(), + cpu_alert: default_cpu_alert(), + mem_alert: default_mem_alert(), + disk_alert: default_disk_alert(), + stats_interval: Default::default(), + region: Default::default(), + instance_id: Default::default(), + created_at: Default::default(), + updated_at: Default::default(), + } + } +} + +fn default_cpu_alert() -> f64 { + 50.0 +} + +fn default_mem_alert() -> f64 { + 75.0 +} + +fn default_disk_alert() -> f64 { + 75.0 +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ServerWithStatus { + pub server: Server, + pub status: ServerStatus, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct ServerActionState { + pub pruning_networks: bool, + pub pruning_containers: bool, + pub pruning_images: bool, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum ServerStatus { + Ok, + NotOk, + Disabled, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug)] +pub struct SystemStats { + pub cpu_perc: f32, // in % + pub mem_used_gb: f64, // in GB + pub mem_total_gb: f64, // in GB + pub disk: DiskUsage, + pub networks: Vec, + pub polling_rate: Timelength, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug)] +pub struct DiskUsage { + pub used_gb: f64, // in GB + pub total_gb: f64, // in GB + pub read_kb: f64, // in kB + pub write_kb: f64, // in kB + pub disks: Vec, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug)] +pub struct SingleDiskUsage { + pub mount: PathBuf, + pub used_gb: f64, // in GB + pub total_gb: f64, // in GB +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug)] +pub struct SystemNetwork { + pub name: String, + pub recieved_kb: f64, // in kB + pub transmitted_kb: f64, // in kB +} diff --git a/lib/types/src/update.rs b/lib/types/src/update.rs new file mode 100644 index 000000000..7959dcb76 --- /dev/null +++ b/lib/types/src/update.rs @@ -0,0 +1,147 @@ +use bson::serde_helpers::hex_string_as_object_id; +use serde::{Deserialize, Serialize}; +use strum_macros::{Display, EnumString}; +use typeshare::typeshare; + +use crate::{monitor_timestamp, Build, Deployment, Operation, Procedure, Server, Version}; + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct Update { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + pub id: String, + pub target: UpdateTarget, + pub operation: Operation, + pub logs: Vec, + pub start_ts: String, + pub end_ts: Option, + pub status: UpdateStatus, + pub success: bool, + pub operator: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct Log { + pub stage: String, + pub command: String, + pub stdout: String, + pub stderr: String, + pub success: bool, + pub start_ts: String, + pub end_ts: String, +} + +impl Log { + pub fn simple(stage: &str, msg: String) -> Log { + let ts = monitor_timestamp(); + Log { + stage: stage.to_string(), + stdout: msg, + success: true, + start_ts: ts.clone(), + end_ts: ts, + ..Default::default() + } + } + + pub fn error(stage: &str, msg: String) -> Log { + let ts = monitor_timestamp(); + Log { + stage: stage.to_string(), + stderr: msg, + start_ts: ts.clone(), + end_ts: ts, + success: false, + ..Default::default() + } + } +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(tag = "type", content = "id")] +pub enum UpdateTarget { + System, + Build(String), + Deployment(String), + Server(String), + Procedure(String), +} + +impl Default for UpdateTarget { + fn default() -> Self { + UpdateTarget::System + } +} + +impl From<&Build> for UpdateTarget { + fn from(build: &Build) -> Self { + Self::Build(build.id.clone()) + } +} + +impl From<&Build> for Option { + fn from(build: &Build) -> Self { + Some(UpdateTarget::Build(build.id.clone())) + } +} + +impl From<&Deployment> for UpdateTarget { + fn from(deployment: &Deployment) -> Self { + Self::Deployment(deployment.id.clone()) + } +} + +impl From<&Deployment> for Option { + fn from(deployment: &Deployment) -> Self { + Some(UpdateTarget::Deployment(deployment.id.clone())) + } +} + +impl From<&Server> for UpdateTarget { + fn from(server: &Server) -> Self { + Self::Server(server.id.clone()) + } +} + +impl From<&Server> for Option { + fn from(server: &Server) -> Self { + Some(UpdateTarget::Server(server.id.clone())) + } +} + +impl From<&Procedure> for UpdateTarget { + fn from(procedure: &Procedure) -> Self { + Self::Procedure(procedure.id.clone()) + } +} + +impl From<&Procedure> for Option { + fn from(procedure: &Procedure) -> Self { + Some(UpdateTarget::Procedure(procedure.id.clone())) + } +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum UpdateStatus { + Queued, + InProgress, + Complete, +} + +impl Default for UpdateStatus { + fn default() -> Self { + UpdateStatus::Complete + } +} diff --git a/lib/types/src/user.rs b/lib/types/src/user.rs new file mode 100644 index 000000000..80209ab1d --- /dev/null +++ b/lib/types/src/user.rs @@ -0,0 +1,70 @@ +use bson::serde_helpers::hex_string_as_object_id; +use diff::Diff; +use serde::{Deserialize, Serialize}; +use typeshare::typeshare; + +use crate::diff::*; + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct User { + #[serde( + default, + rename = "_id", + skip_serializing_if = "String::is_empty", + with = "hex_string_as_object_id" + )] + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub id: String, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub username: String, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub enabled: bool, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub admin: bool, + + #[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))] + pub create_server_permissions: bool, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub avatar: Option, + + // used with auth + #[serde(default)] + #[diff(attr(#[serde(skip_serializing_if = "vec_diff_no_change")]))] + pub secrets: Vec, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub password: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub github_id: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + #[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))] + pub google_id: Option, + + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + pub created_at: String, + #[serde(default)] + #[diff(attr(#[serde(skip)]))] + pub updated_at: String, +} + +#[typeshare] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)] +#[diff(attr(#[derive(Debug, Serialize)]))] +pub struct ApiSecret { + pub name: String, + pub hash: String, + pub created_at: String, + pub expires: Option, +}