move to string timestamps

This commit is contained in:
mbecker20
2022-12-18 05:42:58 +00:00
parent 0e913ac420
commit 0b3bd899fe
17 changed files with 498 additions and 121 deletions

6
.vscode/tasks.json vendored
View File

@@ -129,6 +129,12 @@
"cwd": "${workspaceFolder}/tests"
},
"problemMatcher": []
},
{
"type": "shell",
"command": "typeshare ./lib/types --lang=typescript --output-file=types.d.ts",
"label": "generate typescript types",
"problemMatcher": []
}
]
}

29
Cargo.lock generated
View File

@@ -282,9 +282,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.22"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -1350,15 +1350,18 @@ dependencies = [
name = "monitor_types"
version = "0.1.1"
dependencies = [
"anyhow",
"async_timing_util",
"bollard",
"bson",
"chrono",
"derive_builder",
"diff-struct",
"serde",
"serde_derive",
"strum",
"strum_macros",
"typeshare",
]
[[package]]
@@ -2597,6 +2600,28 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "typeshare"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f096d7253207ace684191e2c22d6480345975c15bbccd7c14d5de713f08bd6"
dependencies = [
"chrono",
"serde",
"serde_json",
"typeshare-annotation",
]
[[package]]
name = "typeshare-annotation"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389b0235d70d7c762268e3b693e5efbe0879b036de868a39188309e2ced169ec"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "unicase"
version = "2.6.0"

View File

@@ -3,6 +3,10 @@ name = "monitor_cli"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "monitor"
path = "src/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -1,11 +1,10 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use diff::Diff;
use helpers::to_monitor_name;
use mungos::{doc, to_bson};
use types::{
traits::Permissioned, Build, Log, Operation, PermissionLevel, Update, UpdateStatus,
UpdateTarget,
UpdateTarget, monitor_timestamp,
};
use crate::{
@@ -40,18 +39,17 @@ impl State {
) -> anyhow::Result<Build> {
self.get_server_check_permissions(&server_id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let build = Build {
name: to_monitor_name(name),
server_id,
permissions: [(user.id.clone(), PermissionLevel::Write)]
.into_iter()
.collect(),
created_at: start_ts,
updated_at: start_ts,
created_at: start_ts.clone(),
updated_at: start_ts.clone(),
..Default::default()
};
let start_ts = unix_timestamp_ms() as i64;
let build_id = self
.db
.builds
@@ -63,7 +61,7 @@ impl State {
target: UpdateTarget::Build(build_id),
operation: Operation::CreateBuild,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
success: true,
..Default::default()
@@ -89,7 +87,7 @@ impl State {
let build = self
.get_build_check_permissions(build_id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let server = self.db.get_server(&build.server_id).await?;
let delete_repo_log = self
.periphery
@@ -101,7 +99,7 @@ impl State {
target: UpdateTarget::System,
operation: Operation::DeleteDeployment,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
logs: vec![
delete_repo_log,
@@ -125,14 +123,14 @@ impl State {
let current_build = self
.get_build_check_permissions(&new_build.id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
// none of these should be changed through this method
new_build.name = current_build.name.clone();
new_build.permissions = current_build.permissions.clone();
new_build.server_id = current_build.server_id.clone();
new_build.created_at = current_build.created_at;
new_build.updated_at = start_ts;
new_build.created_at = current_build.created_at.clone();
new_build.updated_at = start_ts.clone();
self.db
.builds
@@ -172,7 +170,7 @@ impl State {
}
}
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
update.success = all_logs_success(&update.logs);
update.status = UpdateStatus::Complete;
@@ -191,7 +189,7 @@ impl State {
let mut update = Update {
target: UpdateTarget::Build(build_id.to_string()),
operation: Operation::BuildBuild,
start_ts: unix_timestamp_ms() as i64,
start_ts: monitor_timestamp(),
status: UpdateStatus::InProgress,
operator: user.id.clone(),
success: true,
@@ -231,7 +229,7 @@ impl State {
}
}
update.status = UpdateStatus::Complete;
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
self.update_update(update.clone()).await?;
Ok(update)
}
@@ -248,7 +246,7 @@ impl State {
let mut update = Update {
target: UpdateTarget::Build(build_id.to_string()),
operation: Operation::RecloneBuild,
start_ts: unix_timestamp_ms() as i64,
start_ts: monitor_timestamp(),
status: UpdateStatus::InProgress,
operator: user.id.clone(),
success: true,
@@ -270,7 +268,7 @@ impl State {
};
update.status = UpdateStatus::Complete;
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
self.update_update(update.clone()).await?;

View File

@@ -1,10 +1,9 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use diff::Diff;
use helpers::to_monitor_name;
use types::{
traits::Permissioned, Deployment, Log, Operation, PermissionLevel, Update, UpdateStatus,
UpdateTarget,
UpdateTarget, monitor_timestamp,
};
use crate::{
@@ -39,15 +38,15 @@ impl State {
) -> anyhow::Result<Deployment> {
self.get_server_check_permissions(&server_id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let deployment = Deployment {
name: to_monitor_name(name),
server_id,
permissions: [(user.id.clone(), PermissionLevel::Write)]
.into_iter()
.collect(),
created_at: start_ts,
updated_at: start_ts,
created_at: start_ts.clone(),
updated_at: start_ts.clone(),
..Default::default()
};
let deployment_id = self
@@ -61,7 +60,7 @@ impl State {
target: UpdateTarget::Deployment(deployment_id),
operation: Operation::CreateDeployment,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
success: true,
..Default::default()
@@ -91,7 +90,7 @@ impl State {
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let server = self.db.get_server(&deployment.server_id).await?;
let log = self
.periphery
@@ -108,7 +107,7 @@ impl State {
target: UpdateTarget::System,
operation: Operation::DeleteDeployment,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
logs: vec![
log,
@@ -135,14 +134,14 @@ impl State {
let current_deployment = self
.get_deployment_check_permissions(&new_deployment.id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
// none of these should be changed through this method
new_deployment.name = current_deployment.name.clone();
new_deployment.permissions = current_deployment.permissions.clone();
new_deployment.server_id = current_deployment.server_id.clone();
new_deployment.created_at = current_deployment.created_at;
new_deployment.updated_at = start_ts;
new_deployment.created_at = current_deployment.created_at.clone();
new_deployment.updated_at = start_ts.clone();
self.db
.deployments
@@ -185,7 +184,7 @@ impl State {
}
}
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
update.success = all_logs_success(&update.logs);
update.status = UpdateStatus::Complete;
@@ -206,7 +205,7 @@ impl State {
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::RecloneDeployment,
start_ts: unix_timestamp_ms() as i64,
start_ts: monitor_timestamp(),
status: UpdateStatus::InProgress,
operator: user.id.clone(),
success: true,
@@ -228,7 +227,7 @@ impl State {
};
update.status = UpdateStatus::Complete;
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
self.update_update(update.clone()).await?;
@@ -264,7 +263,7 @@ impl State {
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::DeployContainer,
start_ts: unix_timestamp_ms() as i64,
start_ts: monitor_timestamp(),
status: UpdateStatus::InProgress,
operator: user.id.clone(),
success: true,
@@ -278,7 +277,7 @@ impl State {
update.success = deploy_log.success;
update.logs.push(deploy_log);
update.status = UpdateStatus::Complete;
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
self.update_update(update.clone()).await?;
@@ -290,7 +289,7 @@ impl State {
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
@@ -325,7 +324,7 @@ impl State {
}
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
update.status = UpdateStatus::Complete;
self.update_update(update.clone()).await?;
@@ -338,7 +337,7 @@ impl State {
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
@@ -373,7 +372,7 @@ impl State {
}
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
update.status = UpdateStatus::Complete;
self.update_update(update.clone()).await?;
@@ -386,7 +385,7 @@ impl State {
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
@@ -421,7 +420,7 @@ impl State {
}
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
update.status = UpdateStatus::Complete;
self.update_update(update.clone()).await?;

View File

@@ -1,10 +1,9 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use diff::Diff;
use helpers::to_monitor_name;
use types::{
traits::Permissioned, Log, Operation, PermissionLevel, Procedure, ProcedureOperation::*,
ProcedureStage, Update, UpdateStatus, UpdateTarget,
ProcedureStage, Update, UpdateStatus, UpdateTarget, monitor_timestamp,
};
use crate::{auth::RequestUser, state::State};
@@ -32,14 +31,14 @@ impl State {
name: &str,
user: &RequestUser,
) -> anyhow::Result<Procedure> {
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let procedure = Procedure {
name: to_monitor_name(name),
permissions: [(user.id.clone(), PermissionLevel::Write)]
.into_iter()
.collect(),
created_at: start_ts,
updated_at: start_ts,
created_at: start_ts.clone(),
updated_at: start_ts.clone(),
..Default::default()
};
let procedure_id = self
@@ -53,7 +52,7 @@ impl State {
target: UpdateTarget::Procedure(procedure_id),
operation: Operation::CreateProcedure,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
success: true,
..Default::default()
@@ -81,7 +80,7 @@ impl State {
let procedure = self
.get_procedure_check_permissions(id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
self.db
.procedures
.delete_one(id)
@@ -91,7 +90,7 @@ impl State {
target: UpdateTarget::System,
operation: Operation::DeleteProcedure,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
logs: vec![Log::simple(
"delete deployment",
@@ -112,13 +111,13 @@ impl State {
let current_procedure = self
.get_procedure_check_permissions(&new_procedure.id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
// none of these should be changed through this method
new_procedure.name = current_procedure.name.clone();
new_procedure.permissions = current_procedure.permissions.clone();
new_procedure.created_at = current_procedure.created_at;
new_procedure.updated_at = start_ts;
new_procedure.created_at = current_procedure.created_at.clone();
new_procedure.updated_at = start_ts.clone();
// check to make sure no stages have been added that user does not have access to
@@ -136,7 +135,7 @@ impl State {
let update = Update {
operation: Operation::UpdateProcedure,
target: UpdateTarget::Procedure(new_procedure.id.clone()),
end_ts: Some(start_ts),
end_ts: Some(start_ts.clone()),
start_ts,
status: UpdateStatus::Complete,
logs: vec![Log::simple(

View File

@@ -1,10 +1,9 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use diff::Diff;
use helpers::to_monitor_name;
use types::{
traits::Permissioned, Log, Operation, PermissionLevel, Server, Update, UpdateStatus,
UpdateTarget,
UpdateTarget, monitor_timestamp,
};
use crate::{auth::RequestUser, state::State};
@@ -38,15 +37,15 @@ impl State {
"user does not have permissions to add server (not admin)"
));
}
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let server = Server {
name: to_monitor_name(name),
address,
permissions: [(user.id.clone(), PermissionLevel::Write)]
.into_iter()
.collect(),
created_at: start_ts,
updated_at: start_ts,
created_at: start_ts.clone(),
updated_at: start_ts.clone(),
..Default::default()
};
let server_id = self
@@ -60,7 +59,7 @@ impl State {
target: UpdateTarget::Server(server_id),
operation: Operation::CreateServer,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
success: true,
..Default::default()
@@ -91,13 +90,13 @@ impl State {
let server = self
.get_server_check_permissions(server_id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
self.db.servers.delete_one(&server_id).await?;
let update = Update {
target: UpdateTarget::System,
operation: Operation::DeleteServer,
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
operator: user.id.clone(),
logs: vec![Log::simple(
"delete server",
@@ -118,11 +117,11 @@ impl State {
let current_server = self
.get_server_check_permissions(&new_server.id, user, PermissionLevel::Write)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
new_server.permissions = current_server.permissions.clone();
new_server.created_at = current_server.created_at;
new_server.updated_at = start_ts;
new_server.created_at = current_server.created_at.clone();
new_server.updated_at = start_ts.clone();
let diff = current_server.diff(&new_server);
@@ -136,7 +135,7 @@ impl State {
operation: Operation::UpdateServer,
target: UpdateTarget::Server(new_server.id.clone()),
start_ts,
end_ts: Some(unix_timestamp_ms() as i64),
end_ts: Some(monitor_timestamp()),
status: UpdateStatus::Complete,
logs: vec![Log::simple(
"server update",

View File

@@ -1,5 +1,4 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use axum::{
extract::Path,
routing::{delete, post},
@@ -7,7 +6,7 @@ use axum::{
};
use helpers::{generate_secret, handle_anyhow_error};
use mungos::{doc, to_bson, Deserialize, Document, Update};
use types::ApiSecret;
use types::{monitor_timestamp, ApiSecret};
use crate::{auth::RequestUserExtension, state::StateExtension};
@@ -17,7 +16,7 @@ const BCRYPT_COST: u32 = 10;
#[derive(Deserialize)]
struct CreateSecretBody {
name: String,
expires: Option<i64>,
expires: Option<String>,
}
#[derive(Deserialize)]
@@ -50,7 +49,7 @@ impl Into<ApiSecret> for CreateSecretBody {
ApiSecret {
name: self.name,
expires: self.expires,
created_at: unix_timestamp_ms() as i64,
created_at: monitor_timestamp(),
..Default::default()
}
}

View File

@@ -7,7 +7,7 @@ use hmac::{Hmac, Mac};
use jwt::{SignWithKey, VerifyWithKey};
use mungos::{Deserialize, Serialize};
use sha2::Sha256;
use types::{CoreConfig, UserId};
use types::CoreConfig;
use crate::state::State;
@@ -22,7 +22,7 @@ pub struct RequestUser {
#[derive(Serialize, Deserialize)]
pub struct JwtClaims {
pub id: UserId,
pub id: String,
pub iat: u128,
pub exp: u128,
}

View File

@@ -3,6 +3,7 @@ use async_timing_util::unix_timestamp_ms;
use axum::{routing::post, Extension, Json, Router};
use helpers::handle_anyhow_error;
use mungos::{doc, Deserialize, Document, Update};
use types::unix_from_monitor_ts;
use crate::state::StateExtension;
@@ -36,6 +37,7 @@ pub async fn login(
let ts = unix_timestamp_ms() as i64;
for s in user.secrets {
if let Some(expires) = s.expires {
let expires = unix_from_monitor_ts(&expires)?;
if expires < ts {
state
.db

View File

@@ -18,4 +18,4 @@ toml = "0.5"
run_command = { version = "0.0.5", features = ["async_tokio"] }
rand = "0.8"
futures = "0.3"
futures-util = "0.3.25"
futures-util = "0.3.25"

View File

@@ -2,9 +2,8 @@ use std::{path::PathBuf, str::FromStr};
use ::run_command::async_run_command;
use anyhow::anyhow;
use async_timing_util::unix_timestamp_ms;
use serde::{Deserialize, Serialize};
use types::{Build, Command, Deployment, GithubToken, GithubUsername, Log};
use types::{monitor_timestamp, Build, Command, Deployment, GithubToken, GithubUsername, Log};
use crate::{run_monitor_command, to_monitor_name};
@@ -98,7 +97,7 @@ async fn clone(
};
let repo_url = format!("https://{access_token}github.com/{repo}.git");
let command = format!("git clone {repo_url} {destination}{branch}");
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let output = async_run_command(&command).await;
let command = if access_token.len() > 0 {
command.replace(&access_token, "<TOKEN>")
@@ -112,6 +111,6 @@ async fn clone(
stdout: output.stdout,
stderr: output.stderr,
start_ts,
end_ts: unix_timestamp_ms() as i64,
end_ts: monitor_timestamp(),
}
}

View File

@@ -1,12 +1,11 @@
use std::{fs::File, io::Read, net::SocketAddr, str::FromStr};
use anyhow::Context;
use async_timing_util::unix_timestamp_ms;
use axum::http::StatusCode;
use rand::{distributions::Alphanumeric, Rng};
use run_command::{async_run_command, CommandOutput};
use serde::de::DeserializeOwned;
use types::Log;
use types::{monitor_timestamp, Log};
pub mod docker;
pub mod git;
@@ -26,7 +25,12 @@ pub fn parse_config_file<T: DeserializeOwned>(path: &str) -> anyhow::Result<T> {
Ok(config)
}
pub fn output_into_log(stage: &str, command: String, start_ts: i64, output: CommandOutput) -> Log {
pub fn output_into_log(
stage: &str,
command: String,
start_ts: String,
output: CommandOutput,
) -> Log {
let success = output.success();
Log {
stage: stage.to_string(),
@@ -35,7 +39,7 @@ pub fn output_into_log(stage: &str, command: String, start_ts: i64, output: Comm
command,
success,
start_ts,
end_ts: unix_timestamp_ms() as i64,
end_ts: monitor_timestamp(),
}
}
@@ -48,7 +52,7 @@ pub fn to_monitor_name(name: &str) -> String {
}
pub async fn run_monitor_command(stage: &str, command: String) -> Log {
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let output = async_run_command(&command).await;
output_into_log(stage, command, start_ts, output)
}

View File

@@ -17,4 +17,7 @@ strum_macros = "0.24"
async_timing_util = "0.1.12"
diff-struct = "0.5"
bollard = "0.13"
derive_builder = "0.12"
derive_builder = "0.12"
typeshare = "1.0.0"
chrono = "0.4"
anyhow = "1.0"

View File

@@ -1,24 +1,21 @@
use std::{collections::HashMap, path::PathBuf};
use async_timing_util::{unix_timestamp_ms, Timelength};
use anyhow::Context;
use async_timing_util::Timelength;
use bson::serde_helpers::hex_string_as_object_id;
use chrono::{DateTime, Utc};
use derive_builder::Builder;
use diff::{Diff, HashMapDiff, OptionDiff, VecDiff};
use serde::{Deserialize, Serialize};
use strum_macros::{Display, EnumString};
pub use bollard::service::{ImageSummary, Network};
use typeshare::typeshare;
pub mod traits;
pub const PERIPHERY_BUILDER_BUSY: &str = "builder is busy";
pub type UserId = String;
pub type ServerId = String;
pub type DeploymentId = String;
pub type BuildId = String;
pub type ProcedureId = String;
pub type GithubUsername = String;
pub type GithubToken = String;
pub type GithubAccounts = HashMap<GithubUsername, GithubToken>;
@@ -29,8 +26,10 @@ pub type DockerAccounts = HashMap<DockerUsername, DockerToken>;
pub type SecretsMap = HashMap<String, String>; // these are used for injection into deployments run commands
pub type PermissionsMap = HashMap<UserId, PermissionLevel>;
#[typeshare]
pub type PermissionsMap = HashMap<String, PermissionLevel>;
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff)]
#[diff(attr(#[derive(Debug, Serialize)]))]
pub struct User {
@@ -70,7 +69,7 @@ pub struct User {
#[serde(skip_serializing_if = "Option::is_none")]
#[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))]
pub github_id: Option<i64>,
pub github_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))]
@@ -78,21 +77,23 @@ pub struct User {
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
pub created_at: i64,
pub created_at: String,
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
pub updated_at: i64,
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: i64,
pub expires: Option<i64>,
pub created_at: String,
pub expires: Option<String>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Diff, Builder)]
#[diff(attr(#[derive(Debug, Serialize)]))]
pub struct Server {
@@ -130,7 +131,7 @@ pub struct Server {
#[serde(skip_serializing_if = "Option::is_none")]
#[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))]
pub stats_interval: Option<i64>,
pub stats_interval: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))]
@@ -143,11 +144,11 @@ pub struct Server {
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub created_at: i64,
pub created_at: String,
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub updated_at: i64,
pub updated_at: String,
}
impl Default for Server {
@@ -182,6 +183,7 @@ fn default_disk_alert() -> f64 {
75.0
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)]
#[diff(attr(#[derive(Debug, Serialize)]))]
pub struct Deployment {
@@ -199,7 +201,7 @@ pub struct Deployment {
pub name: String, // must be formatted to be compat with docker
#[diff(attr(#[serde(skip_serializing_if = "Option::is_none")]))]
pub server_id: ServerId,
pub server_id: String,
#[serde(default)]
#[diff(attr(#[serde(skip_serializing_if = "hashmap_diff_no_change")]))]
@@ -211,7 +213,7 @@ pub struct Deployment {
#[serde(skip_serializing_if = "Option::is_none")]
#[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))]
pub build_id: Option<BuildId>,
pub build_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[diff(attr(#[serde(skip_serializing_if = "option_diff_no_change")]))]
@@ -237,19 +239,21 @@ pub struct Deployment {
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub created_at: i64,
pub created_at: String,
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub updated_at: i64,
pub updated_at: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct DeploymentWithContainer {
pub deployment: Deployment,
pub container: Option<BasicContainerInfo>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)]
#[diff(attr(#[derive(Debug, Serialize)]))]
pub struct Build {
@@ -304,13 +308,14 @@ pub struct Build {
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub created_at: i64,
pub created_at: String,
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub updated_at: i64,
pub updated_at: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Update {
#[serde(
@@ -323,8 +328,8 @@ pub struct Update {
pub target: UpdateTarget,
pub operation: Operation,
pub logs: Vec<Log>,
pub start_ts: i64,
pub end_ts: Option<i64>,
pub start_ts: String,
pub end_ts: Option<String>,
pub status: UpdateStatus,
pub success: bool,
pub operator: String,
@@ -332,6 +337,7 @@ pub struct Update {
pub version: Option<Version>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)]
#[diff(attr(#[derive(Debug, Serialize)]))]
pub struct Procedure {
@@ -351,13 +357,14 @@ pub struct Procedure {
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub created_at: i64,
pub created_at: String,
#[serde(default)]
#[diff(attr(#[serde(skip)]))]
#[builder(setter(skip))]
pub updated_at: i64,
pub updated_at: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)]
#[diff(attr(#[derive(Debug, Serialize)]))]
pub struct ProcedureStage {
@@ -365,6 +372,7 @@ pub struct ProcedureStage {
pub target_id: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, Diff, Builder)]
#[diff(attr(#[derive(Debug, Serialize, PartialEq)]))]
pub struct DockerBuildArgs {
@@ -373,6 +381,7 @@ pub struct DockerBuildArgs {
pub build_args: Vec<EnvironmentVar>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, Diff, Builder)]
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
pub struct DockerRunArgs {
@@ -404,6 +413,7 @@ pub struct DockerRunArgs {
pub docker_account: Option<String>, // the username of the dockerhub account
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BasicContainerInfo {
pub name: String,
@@ -412,6 +422,7 @@ pub struct BasicContainerInfo {
pub status: Option<String>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DockerContainerStats {
#[serde(alias = "Name")]
@@ -430,6 +441,7 @@ pub struct DockerContainerStats {
pub pids: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Log {
pub stage: String,
@@ -437,29 +449,29 @@ pub struct Log {
pub stdout: String,
pub stderr: String,
pub success: bool,
pub start_ts: i64,
pub end_ts: i64,
pub start_ts: String,
pub end_ts: String,
}
impl Log {
pub fn simple(stage: &str, msg: String) -> Log {
let ts = unix_timestamp_ms() as i64;
let ts = monitor_timestamp();
Log {
stage: stage.to_string(),
stdout: msg,
success: true,
start_ts: ts,
start_ts: ts.clone(),
end_ts: ts,
..Default::default()
}
}
pub fn error(stage: &str, msg: String) -> Log {
let ts = unix_timestamp_ms() as i64;
let ts = monitor_timestamp();
Log {
stage: stage.to_string(),
stderr: msg,
start_ts: ts,
start_ts: ts.clone(),
end_ts: ts,
success: false,
..Default::default()
@@ -467,6 +479,7 @@ impl Log {
}
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Diff)]
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
pub struct Command {
@@ -474,12 +487,13 @@ 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: u64,
pub minor: u64,
pub patch: u64,
pub major: i32,
pub minor: i32,
pub patch: i32,
}
impl ToString for Version {
@@ -494,6 +508,7 @@ impl Version {
}
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)]
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
pub struct Conversion {
@@ -501,6 +516,7 @@ pub struct Conversion {
pub container: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Diff)]
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
pub struct EnvironmentVar {
@@ -583,12 +599,14 @@ fn default_repo_dir() -> String {
"/repos".to_string()
}
#[typeshare]
#[derive(Deserialize, Debug)]
pub struct UserCredentials {
pub username: String,
pub password: String,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug)]
pub struct SystemStats {
pub cpu_perc: f32, // in %
@@ -598,6 +616,7 @@ pub struct SystemStats {
pub networks: Vec<SystemNetwork>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug)]
pub struct DiskUsage {
pub used_gb: f64, // in GB
@@ -607,6 +626,7 @@ pub struct DiskUsage {
pub disks: Vec<SingleDiskUsage>,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug)]
pub struct SingleDiskUsage {
pub mount: PathBuf,
@@ -614,6 +634,7 @@ pub struct SingleDiskUsage {
pub total_gb: f64, // in GB
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug)]
pub struct SystemNetwork {
pub name: String,
@@ -621,6 +642,7 @@ pub struct SystemNetwork {
pub transmitted_kb: f64, // in kB
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
@@ -629,14 +651,15 @@ pub enum AccountType {
Docker,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "id")]
pub enum UpdateTarget {
System,
Build(BuildId),
Deployment(DeploymentId),
Server(ServerId),
Procedure(ProcedureId),
Build(String),
Deployment(String),
Server(String),
Procedure(String),
}
impl Default for UpdateTarget {
@@ -645,6 +668,7 @@ impl Default for UpdateTarget {
}
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
@@ -660,6 +684,7 @@ impl Default for UpdateStatus {
}
}
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff,
)]
@@ -708,6 +733,7 @@ impl Default for Operation {
}
}
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff,
)]
@@ -745,6 +771,7 @@ impl Default for ProcedureOperation {
}
}
#[typeshare]
#[derive(
Serialize,
Deserialize,
@@ -781,6 +808,7 @@ impl Default for &PermissionLevel {
}
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
@@ -790,6 +818,7 @@ pub enum PermissionsTarget {
Build,
}
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
@@ -803,6 +832,7 @@ pub enum DockerContainerState {
Dead,
}
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy, Diff,
)]
@@ -858,3 +888,13 @@ fn docker_run_args_diff_no_change(dra: &DockerRunArgsDiff) -> bool {
fn restart_mode_diff_no_change(restart_mode: &RestartModeDiff) -> bool {
restart_mode == &RestartModeDiff::NoChange
}
pub fn monitor_timestamp() -> String {
Utc::now().to_rfc3339()
}
pub fn unix_from_monitor_ts(ts: &str) -> anyhow::Result<i64> {
Ok(DateTime::parse_from_rfc3339(ts)
.context("failed to parse rfc3339 timestamp")?
.timestamp_millis())
}

298
types.d.ts vendored Normal file
View File

@@ -0,0 +1,298 @@
/*
Generated by typeshare 1.0.0
*/
export type PermissionsMap = Record<string, PermissionLevel>;
export interface User {
_id?: string;
username: string;
enabled: boolean;
admin: boolean;
create_server_permissions: boolean;
avatar?: string;
secrets?: ApiSecret[];
password?: string;
github_id?: string;
google_id?: string;
created_at?: string;
updated_at?: string;
}
export interface ApiSecret {
name: string;
hash: string;
created_at: string;
expires?: string;
}
export interface Server {
_id?: string;
name: string;
address: string;
permissions?: PermissionsMap;
to_notify?: string[];
cpu_alert?: number;
mem_alert?: number;
disk_alert?: number;
stats_interval?: number;
region?: string;
instance_id?: string;
created_at?: string;
updated_at?: string;
}
export interface Deployment {
_id?: string;
name: string;
server_id: string;
permissions?: PermissionsMap;
docker_run_args: DockerRunArgs;
build_id?: string;
build_version?: Version;
repo?: string;
branch?: string;
github_account?: string;
on_clone?: Command;
created_at?: string;
updated_at?: string;
}
export interface DeploymentWithContainer {
deployment: Deployment;
container?: BasicContainerInfo;
}
export interface Build {
_id?: string;
name: string;
permissions: PermissionsMap;
server_id: string;
version: Version;
repo?: string;
branch?: string;
github_account?: string;
on_clone?: Command;
pre_build?: Command;
docker_build_args?: DockerBuildArgs;
docker_account?: string;
created_at?: string;
updated_at?: string;
}
export interface Update {
_id?: string;
target: UpdateTarget;
operation: Operation;
logs: Log[];
start_ts: string;
end_ts?: string;
status: UpdateStatus;
success: boolean;
operator: string;
version?: Version;
}
export interface Procedure {
_id?: string;
name: string;
stages: ProcedureStage[];
permissions: PermissionsMap;
created_at?: string;
updated_at?: string;
}
export interface ProcedureStage {
operation: ProcedureOperation;
target_id: string;
}
export interface DockerBuildArgs {
build_path: string;
dockerfile_path?: string;
build_args: EnvironmentVar[];
}
export interface DockerRunArgs {
image: string;
ports: Conversion[];
volumes: Conversion[];
environment: EnvironmentVar[];
network?: string;
restart: RestartMode;
post_image?: string;
container_user?: string;
docker_account?: string;
}
export interface BasicContainerInfo {
name: string;
id: string;
state: DockerContainerState;
status?: string;
}
export interface DockerContainerStats {
name: string;
cpu_perc: string;
mem_perc: string;
mem_usage: string;
net_io: string;
block_io: string;
pids: string;
}
export interface Log {
stage: string;
command: string;
stdout: string;
stderr: string;
success: boolean;
start_ts: string;
end_ts: string;
}
export interface Command {
path: string;
command: string;
}
export interface Version {
major: number;
minor: number;
patch: number;
}
export interface Conversion {
local: string;
container: string;
}
export interface EnvironmentVar {
variable: string;
value: string;
}
export interface UserCredentials {
username: string;
password: string;
}
export interface SystemStats {
cpu_perc: number;
mem_used_gb: number;
mem_total_gb: number;
disk: DiskUsage;
networks: SystemNetwork[];
}
export interface DiskUsage {
used_gb: number;
total_gb: number;
read_kb: number;
write_kb: number;
disks: SingleDiskUsage[];
}
export interface SingleDiskUsage {
mount: string;
used_gb: number;
total_gb: number;
}
export interface SystemNetwork {
name: string;
recieved_kb: number;
transmitted_kb: number;
}
export enum AccountType {
Github = "github",
Docker = "docker",
}
export type UpdateTarget =
| { type: "System", id?: undefined }
| { type: "Build", id: string }
| { type: "Deployment", id: string }
| { type: "Server", id: string }
| { type: "Procedure", id: string };
export enum UpdateStatus {
Queued = "queued",
InProgress = "in_progress",
Complete = "complete",
}
export enum Operation {
None = "none",
CreateServer = "create_server",
UpdateServer = "update_server",
DeleteServer = "delete_server",
PruneImagesServer = "prune_images_server",
PruneContainersServer = "prune_containers_server",
PruneNetworksServer = "prune_networks_server",
CreateBuild = "create_build",
UpdateBuild = "update_build",
DeleteBuild = "delete_build",
BuildBuild = "build_build",
RecloneBuild = "reclone_build",
CreateDeployment = "create_deployment",
UpdateDeployment = "update_deployment",
DeleteDeployment = "delete_deployment",
DeployContainer = "deploy_container",
StopContainer = "stop_container",
StartContainer = "start_container",
RemoveContainer = "remove_container",
PullDeployment = "pull_deployment",
RecloneDeployment = "reclone_deployment",
CreateProcedure = "create_procedure",
UpdateProcedure = "update_procedure",
DeleteProcedure = "delete_procedure",
}
export enum ProcedureOperation {
None = "none",
PruneImagesServer = "prune_images_server",
PruneContainersServer = "prune_containers_server",
PruneNetworksServer = "prune_networks_server",
BuildBuild = "build_build",
RecloneBuild = "reclone_build",
DeployContainer = "deploy_container",
StopContainer = "stop_container",
StartContainer = "start_container",
RemoveContainer = "remove_container",
PullDeployment = "pull_deployment",
RecloneDeployment = "reclone_deployment",
RunProcedure = "run_procedure",
}
export enum PermissionLevel {
None = "none",
Read = "read",
Write = "write",
}
export enum PermissionsTarget {
Server = "server",
Deployment = "deployment",
Build = "build",
}
export enum DockerContainerState {
Created = "created",
Restarting = "restarting",
Running = "running",
Removing = "removing",
Paused = "paused",
Exited = "exited",
Dead = "dead",
}
export enum RestartMode {
NoRestart = "no",
OnFailure = "on-failure",
Always = "always",
UnlessStopped = "unless-stopped",
}

2
typeshare.toml Normal file
View File

@@ -0,0 +1,2 @@
[typescript.type_mappings]
"PathBuf" = "string"