You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

137 lines
3.9 KiB

use serde::{Deserialize, Serialize};
use std::fmt;
use std::time::SystemTime;
use strum::Display;
#[cfg(feature = "server")]
mod server {
pub use crate::models::schema::*;
pub use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
pub use diesel_derive_enum::DbEnum;
}
#[cfg(feature = "server")]
use self::server::*;
use crate::{
config::get_self_id, conv::systime_to_string, jobs::NamedJobBatch, platform, types::Id,
u_runner::ExecResult,
};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Display)]
#[cfg_attr(
feature = "server",
derive(DbEnum),
ExistingTypePath = "sql_types::Agentstate"
)]
pub enum AgentState {
New,
Active,
Banned,
}
//belongs_to
#[derive(Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(
feature = "server",
derive(Identifiable, Queryable, Insertable, AsChangeset),
diesel(table_name = agents)
)]
pub struct Agent {
pub alias: Option<String>,
pub hostname: String,
pub host_info: String,
pub id: Id,
pub ip_gray: Option<String>,
pub ip_white: Option<String>,
pub is_root: bool,
pub is_root_allowed: bool,
pub last_active: SystemTime,
pub platform: String,
pub regtime: SystemTime,
pub state: AgentState,
pub token: Option<String>,
pub username: String,
}
impl Agent {
pub fn empty() -> Self {
Self {
alias: None,
id: get_self_id(),
hostname: String::new(),
host_info: String::new(),
is_root: false,
is_root_allowed: false,
last_active: SystemTime::now(),
platform: String::new(),
regtime: SystemTime::now(),
state: AgentState::New,
token: None,
username: String::new(),
ip_gray: None,
ip_white: None,
}
}
pub fn with_current_platform() -> Self {
Self {
platform: platform::current_as_string(),
..Self::empty()
}
}
pub fn touch(&mut self) {
self.last_active = SystemTime::now();
}
pub async fn gather() -> Self {
#[cfg(unix)]
let cmds = vec![
("hostname", "uname -a"),
("host_info", "hostnamectl --json=pretty"),
("is_root", "id -u"),
("username", "id -un"),
];
#[cfg(windows)]
let cmds = vec![
("hostname", "uname -a"),
("host_info", "hostnamectl --json=pretty"),
("is_root", "id -u"),
("username", "id -un"),
];
let mut builder = NamedJobBatch::from_shell(cmds).unwrap_one().wait().await;
let decoder =
|job_result: ExecResult| job_result.unwrap().to_str_result().trim().to_string();
Self {
hostname: decoder(builder.pop("hostname")),
host_info: decoder(builder.pop("host_info")),
is_root: &decoder(builder.pop("is_root")) == "0",
username: decoder(builder.pop("username")),
..Self::with_current_platform()
}
}
}
impl fmt::Debug for Agent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Agent")
.field("alias", &self.alias)
.field("hostname", &self.hostname)
.field("host_info", &self.host_info)
.field("id", &self.id.to_string())
.field("ip_gray", &self.ip_gray)
.field("ip_white", &self.ip_white)
.field("is_root", &self.is_root)
.field("is_root_allowed", &self.is_root_allowed)
.field("last_active", &systime_to_string(self.last_active))
.field("platform", &self.platform)
.field("regtime", &systime_to_string(self.regtime))
.field("state", &self.state)
.field("token", &self.token)
.field("username", &self.username)
.finish()
}
}