finish server api

This commit is contained in:
mbecker20
2023-06-20 07:13:14 +00:00
parent 86379d1c79
commit b903e511b5
16 changed files with 493 additions and 82 deletions

View File

@@ -4,8 +4,8 @@
"prefix": "resolve",
"body": [
"#[async_trait]",
"impl Resolve<${1}, ${2}> for State {",
"\tasync fn resolve(&self, req: ${1}, args: ${2}) -> anyhow::Result<${3}> {",
"impl Resolve<${1}, RequestUser> for State {",
"\tasync fn resolve(&self, ${1} { ${0} }: ${1}, user: RequestUser) -> anyhow::Result<${2}> {",
"\t\ttodo!()",
"\t}",
"}"

1
Cargo.lock generated
View File

@@ -1489,6 +1489,7 @@ dependencies = [
name = "monitor_helpers"
version = "1.0.0"
dependencies = [
"async_timing_util",
"serde",
]

View File

@@ -1,6 +1,6 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use axum::{extract::Query, http::StatusCode, response::Redirect, routing::get, Router};
use monitor_helpers::monitor_timestamp;
use monitor_types::entities::user::User;
use mungos::mongodb::bson::doc;
use serde::Deserialize;
@@ -63,7 +63,7 @@ async fn callback(
.generate(user.id)
.context("failed to generate jwt")?,
None => {
let ts = unix_timestamp_ms() as i64;
let ts = monitor_timestamp();
let no_users_exist = state.db.users.find_one(None, None).await?.is_none();
let user = User {
username: github_user.login,

View File

@@ -194,7 +194,7 @@ impl<T: Clone + Default> Cache<T> {
cache.entry(key).or_default().clone()
}
pub async fn _get_list(&self, filter: Option<impl Fn(&String, &T) -> bool>) -> Vec<T> {
pub async fn get_list(&self, filter: Option<impl Fn(&String, &T) -> bool>) -> Vec<T> {
let cache = self.cache.read().await;
match filter {
Some(filter) => cache

View File

@@ -35,12 +35,12 @@ impl State {
let servers = servers.unwrap();
let futures = servers
.into_iter()
.map(|server| async move { self.update_cache(&server).await });
.map(|server| async move { self.update_cache_for_server(&server).await });
join_all(futures).await;
}
}
pub async fn update_cache(&self, server: &Server) {
pub async fn update_cache_for_server(&self, server: &Server) {
let deployments = self
.db
.deployments

View File

@@ -1,8 +1,9 @@
use monitor_types::requests::api::{
CreateLoginSecret, CreateServer, DeleteLoginSecret, DeleteServer, GetAllSystemStats,
GetBasicSystemStats, GetCpuUsage, GetDiskUsage, GetNetworkUsage, GetPeripheryVersion,
GetServer, GetSystemComponents, GetSystemInformation, GetSystemProcesses, ListServers,
RenameServer, UpdateServer,
GetBasicSystemStats, GetCpuUsage, GetDiskUsage, GetDockerContainers, GetDockerImages,
GetDockerNetworks, GetNetworkUsage, GetPeripheryVersion, GetServer, GetSystemComponents,
GetSystemInformation, GetSystemProcesses, ListServers, PruneDockerContainers,
PruneDockerImages, PruneDockerNetworks, RenameServer, UpdateServer,
};
use resolver_api::{derive::Resolver, Resolve, ResolveToString};
use serde::{Deserialize, Serialize};
@@ -27,6 +28,9 @@ pub enum ApiRequest {
//
GetPeripheryVersion(GetPeripheryVersion),
GetSystemInformation(GetSystemInformation),
GetDockerContainers(GetDockerContainers),
GetDockerImages(GetDockerImages),
GetDockerNetworks(GetDockerNetworks),
GetServer(GetServer),
ListServers(ListServers),
// CRUD
@@ -34,7 +38,7 @@ pub enum ApiRequest {
DeleteServer(DeleteServer),
UpdateServer(UpdateServer),
RenameServer(RenameServer),
// Stats
// STATS
#[to_string_resolver]
GetAllSystemStats(GetAllSystemStats),
#[to_string_resolver]
@@ -49,7 +53,10 @@ pub enum ApiRequest {
GetSystemProcesses(GetSystemProcesses),
#[to_string_resolver]
GetSystemComponents(GetSystemComponents),
// ACTIONS
PruneContainers(PruneDockerContainers),
PruneImages(PruneDockerImages),
PruneNetworks(PruneDockerNetworks),
//
// ==== DEPLOYMENT ====
//

View File

@@ -1,6 +1,6 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use async_trait::async_trait;
use monitor_helpers::monitor_timestamp;
use monitor_types::{
entities::user::ApiSecret,
requests::api::{CreateLoginSecret, CreateLoginSecretResponse, DeleteLoginSecret},
@@ -35,7 +35,7 @@ impl Resolve<CreateLoginSecret, RequestUser> for State {
let secret_str = random_string(SECRET_LENGTH);
let api_secret = ApiSecret {
name: secret.name,
created_at: unix_timestamp_ms() as i64,
created_at: monitor_timestamp(),
expires: secret.expires,
hash: bcrypt::hash(&secret_str, BCRYPT_COST)
.context("failed at hashing secret string")?,

View File

@@ -1,21 +1,26 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use async_trait::async_trait;
use monitor_helpers::monitor_timestamp;
use monitor_types::{
entities::{
server::{stats::SystemInformation, Server},
deployment::BasicContainerInfo,
server::{
docker_image::ImageSummary, docker_network::DockerNetwork, stats::SystemInformation,
Server,
},
update::{Log, Update, UpdateStatus, UpdateTarget},
Operation, PermissionLevel,
},
permissioned::Permissioned,
requests::api::{
CreateServer, DeleteServer, GetAllSystemStats, GetBasicSystemStats, GetCpuUsage,
GetDiskUsage, GetNetworkUsage, GetPeripheryVersion, GetPeripheryVersionResponse, GetServer,
GetSystemComponents, GetSystemInformation, GetSystemProcesses, ListServers, RenameServer,
UpdateServer,
GetDiskUsage, GetDockerContainers, GetDockerImages, GetDockerNetworks, GetNetworkUsage,
GetPeripheryVersion, GetPeripheryVersionResponse, GetServer, GetSystemComponents,
GetSystemInformation, GetSystemProcesses, ListServers, PruneDockerImages,
PruneDockerNetworks, RenameServer, UpdateServer, PruneDockerContainers,
},
};
use mungos::mongodb::bson::doc;
use mungos::mongodb::bson::{doc, to_bson};
use periphery_client::requests;
use resolver_api::{Resolve, ResolveToString};
@@ -77,7 +82,7 @@ impl Resolve<CreateServer, RequestUser> for State {
if !user.is_admin && !user.create_server_permissions {
return Err(anyhow!("user does not have create server permissions"));
}
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let server = Server {
id: Default::default(),
name: req.name,
@@ -93,7 +98,7 @@ impl Resolve<CreateServer, RequestUser> for State {
let server_id = self
.db
.servers
.create_one(server)
.create_one(&server)
.await
.context("failed to add server to db")?;
let server = self.get_server(&server_id).await?;
@@ -101,15 +106,22 @@ impl Resolve<CreateServer, RequestUser> for 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,
logs: vec![
Log::simple(
"create server",
format!("created server\nid: {}\nname: {}", server.id, server.name),
),
Log::simple("config", format!("{:#?}", server.config)),
],
..Default::default()
};
self.add_update(update).await?;
self.update_cache(&server).await;
self.update_cache_for_server(&server).await;
Ok(server)
}
@@ -126,7 +138,7 @@ impl Resolve<DeleteServer, RequestUser> for State {
.get_server_check_permissions(&req.id, &user, PermissionLevel::Update)
.await?;
let start_ts = unix_timestamp_ms() as i64;
let start_ts = monitor_timestamp();
let mut update = Update {
target: UpdateTarget::Server(req.id.clone()),
@@ -152,7 +164,7 @@ impl Resolve<DeleteServer, RequestUser> for State {
Err(e) => Log::error("delete server", format!("failed to delete server\n{e:#?}")),
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.end_ts = Some(monitor_timestamp());
update.status = UpdateStatus::Complete;
update.success = log.success;
update.logs.push(log);
@@ -167,8 +179,47 @@ impl Resolve<DeleteServer, RequestUser> for State {
#[async_trait]
impl Resolve<UpdateServer, RequestUser> for State {
async fn resolve(&self, req: UpdateServer, user: RequestUser) -> anyhow::Result<Server> {
todo!()
async fn resolve(
&self,
UpdateServer { id, config }: UpdateServer,
user: RequestUser,
) -> anyhow::Result<Server> {
if self.action_states.server.busy(&id).await {
return Err(anyhow!("server busy"));
}
let start_ts = monitor_timestamp();
self.get_server_check_permissions(&id, &user, PermissionLevel::Update)
.await?;
self.db
.servers
.update_one(
&id,
mungos::Update::<()>::Set(doc! { "config": to_bson(&config)? }),
)
.await
.context("failed to update server on mongo")?;
let update = Update {
operation: Operation::UpdateServer,
target: UpdateTarget::Server(id.clone()),
start_ts,
end_ts: Some(monitor_timestamp()),
status: UpdateStatus::Complete,
logs: vec![Log::simple(
"server update",
serde_json::to_string_pretty(&config).unwrap(),
)],
operator: user.id.clone(),
success: true,
..Default::default()
};
let new_server = self.get_server(&id).await?;
self.update_cache_for_server(&new_server).await;
self.add_update(update).await?;
Ok(new_server)
}
}
@@ -178,19 +229,36 @@ impl Resolve<RenameServer, RequestUser> for State {
&self,
RenameServer { id, name }: RenameServer,
user: RequestUser,
) -> anyhow::Result<Server> {
self.get_server_check_permissions(&id, &user, PermissionLevel::Update)
) -> anyhow::Result<Update> {
let start_ts = monitor_timestamp();
let server = self
.get_server_check_permissions(&id, &user, PermissionLevel::Update)
.await?;
self.db
.updates
.update_one(
&id,
mungos::Update::<Server>::Set(
doc! { "name": name, "updated_at": unix_timestamp_ms() as i64 },
doc! { "name": &name, "updated_at": monitor_timestamp() },
),
)
.await?;
todo!()
let mut update = Update {
target: UpdateTarget::Deployment(id.clone()),
operation: Operation::RenameServer,
start_ts,
end_ts: Some(monitor_timestamp()),
logs: vec![Log::simple(
"rename server",
format!("renamed server {id} from {} to {name}", server.name),
)],
status: UpdateStatus::Complete,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
Ok(update)
}
}
@@ -370,3 +438,259 @@ impl ResolveToString<GetSystemComponents, RequestUser> for State {
Ok(stats)
}
}
#[async_trait]
impl Resolve<GetDockerImages, RequestUser> for State {
async fn resolve(
&self,
GetDockerImages { server_id }: GetDockerImages,
user: RequestUser,
) -> anyhow::Result<Vec<ImageSummary>> {
let server = self
.get_server_check_permissions(&server_id, &user, PermissionLevel::Read)
.await?;
self.periphery_client(&server)
.request(requests::GetImageList {})
.await
}
}
#[async_trait]
impl Resolve<PruneDockerImages, RequestUser> for State {
async fn resolve(
&self,
PruneDockerImages { server_id }: PruneDockerImages,
user: RequestUser,
) -> anyhow::Result<Update> {
if self.action_states.server.busy(&server_id).await {
return Err(anyhow!("server busy"));
}
let inner = || async {
let server = self
.get_server_check_permissions(&server_id, &user, PermissionLevel::Execute)
.await?;
let start_ts = monitor_timestamp();
let mut update = Update {
target: UpdateTarget::Server(server_id.to_owned()),
operation: Operation::PruneImagesServer,
start_ts,
status: UpdateStatus::InProgress,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let log = match self
.periphery_client(&server)
.request(requests::PruneImages {})
.await
.context(format!("failed to prune images on server {}", server.name))
{
Ok(log) => log,
Err(e) => Log::error("prune images", format!("{e:#?}")),
};
update.success = log.success;
update.status = UpdateStatus::Complete;
update.end_ts = Some(monitor_timestamp());
update.logs.push(log);
self.update_update(update.clone()).await?;
Ok(update)
};
self.action_states
.server
.update_entry(server_id.to_string(), |entry| {
entry.pruning_images = true;
})
.await;
let res = inner().await;
self.action_states
.server
.update_entry(server_id.to_string(), |entry| {
entry.pruning_images = false;
})
.await;
res
}
}
#[async_trait]
impl Resolve<GetDockerNetworks, RequestUser> for State {
async fn resolve(
&self,
GetDockerNetworks { server_id }: GetDockerNetworks,
user: RequestUser,
) -> anyhow::Result<Vec<DockerNetwork>> {
let server = self
.get_server_check_permissions(&server_id, &user, PermissionLevel::Read)
.await?;
self.periphery_client(&server)
.request(requests::GetNetworkList {})
.await
}
}
#[async_trait]
impl Resolve<PruneDockerNetworks, RequestUser> for State {
async fn resolve(
&self,
PruneDockerNetworks { server_id }: PruneDockerNetworks,
user: RequestUser,
) -> anyhow::Result<Update> {
if self.action_states.server.busy(&server_id).await {
return Err(anyhow!("server busy"));
}
let inner = || async {
let server = self
.get_server_check_permissions(&server_id, &user, PermissionLevel::Execute)
.await?;
let start_ts = monitor_timestamp();
let mut update = Update {
target: UpdateTarget::Server(server_id.to_owned()),
operation: Operation::PruneNetworksServer,
start_ts,
status: UpdateStatus::InProgress,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let log = match self
.periphery_client(&server)
.request(requests::PruneNetworks {})
.await
.context(format!(
"failed to prune networks on server {}",
server.name
)) {
Ok(log) => log,
Err(e) => Log::error("prune networks", format!("{e:#?}")),
};
update.success = log.success;
update.status = UpdateStatus::Complete;
update.end_ts = Some(monitor_timestamp());
update.logs.push(log);
self.update_update(update.clone()).await?;
Ok(update)
};
self.action_states
.server
.update_entry(server_id.to_string(), |entry| {
entry.pruning_networks = true;
})
.await;
let res = inner().await;
self.action_states
.server
.update_entry(server_id.to_string(), |entry| {
entry.pruning_networks = false;
})
.await;
res
}
}
#[async_trait]
impl Resolve<GetDockerContainers, RequestUser> for State {
async fn resolve(
&self,
GetDockerContainers { server_id }: GetDockerContainers,
user: RequestUser,
) -> anyhow::Result<Vec<BasicContainerInfo>> {
let server = self
.get_server_check_permissions(&server_id, &user, PermissionLevel::Read)
.await?;
self.periphery_client(&server)
.request(requests::GetContainerList {})
.await
}
}
#[async_trait]
impl Resolve<PruneDockerContainers, RequestUser> for State {
async fn resolve(
&self,
PruneDockerContainers { server_id }: PruneDockerContainers,
user: RequestUser,
) -> anyhow::Result<Update> {
if self.action_states.server.busy(&server_id).await {
return Err(anyhow!("server busy"));
}
let inner = || async {
let server = self
.get_server_check_permissions(&server_id, &user, PermissionLevel::Execute)
.await?;
let start_ts = monitor_timestamp();
let mut update = Update {
target: UpdateTarget::Server(server_id.to_owned()),
operation: Operation::PruneContainersServer,
start_ts,
status: UpdateStatus::InProgress,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let log = match self
.periphery_client(&server)
.request(requests::PruneNetworks {})
.await
.context(format!(
"failed to prune containers on server {}",
server.name
)) {
Ok(log) => log,
Err(e) => Log::error("prune containers", format!("{e:#?}")),
};
update.success = log.success;
update.status = UpdateStatus::Complete;
update.end_ts = Some(monitor_timestamp());
update.logs.push(log);
self.update_update(update.clone()).await?;
Ok(update)
};
self.action_states
.server
.update_entry(server_id.to_string(), |entry| {
entry.pruning_containers = true;
})
.await;
let res = inner().await;
self.action_states
.server
.update_entry(server_id.to_string(), |entry| {
entry.pruning_containers = false;
})
.await;
res
}
}

View File

@@ -8,4 +8,5 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde.workspace = true
serde.workspace = true
async_timing_util.workspace = true

View File

@@ -1,3 +1,5 @@
use async_timing_util::unix_timestamp_ms;
pub fn to_monitor_name(name: &str) -> String {
name.to_lowercase().replace(' ', "_")
}
@@ -9,3 +11,7 @@ pub fn optional_string(string: &str) -> Option<String> {
Some(string.to_string())
}
}
pub fn monitor_timestamp() -> i64 {
unix_timestamp_ms() as i64
}

View File

@@ -219,10 +219,10 @@ pub enum Operation {
CreateServer,
UpdateServer,
DeleteServer,
RenameServer,
PruneImagesServer,
PruneContainersServer,
PruneNetworksServer,
RenameServer,
// build
CreateBuild,

View File

@@ -71,17 +71,29 @@ pub struct ServerConfig {
#[builder(default)]
pub region: String,
#[serde(default = "default_cpu_alert")]
#[builder(default = "default_cpu_alert()")]
pub cpu_alert: f32,
#[serde(default = "default_cpu_warning")]
#[builder(default = "default_cpu_warning()")]
pub cpu_warning: f32,
#[serde(default = "default_mem_alert")]
#[builder(default = "default_mem_alert()")]
pub mem_alert: f64,
#[serde(default = "default_cpu_critical")]
#[builder(default = "default_cpu_critical()")]
pub cpu_critical: f32,
#[serde(default = "default_disk_alert")]
#[builder(default = "default_disk_alert()")]
pub disk_alert: f64,
#[serde(default = "default_mem_warning")]
#[builder(default = "default_mem_warning()")]
pub mem_warning: f64,
#[serde(default = "default_mem_critical")]
#[builder(default = "default_mem_critical()")]
pub mem_critical: f64,
#[serde(default = "default_disk_warning")]
#[builder(default = "default_disk_warning()")]
pub disk_warning: f64,
#[serde(default = "default_disk_critical")]
#[builder(default = "default_disk_critical()")]
pub disk_critical: f64,
#[serde(default)]
#[builder(default)]
@@ -96,16 +108,28 @@ fn default_auto_prune() -> bool {
true
}
fn default_cpu_alert() -> f32 {
fn default_cpu_warning() -> f32 {
90.0
}
fn default_cpu_critical() -> f32 {
99.0
}
fn default_mem_warning() -> f64 {
75.0
}
fn default_mem_critical() -> f64 {
95.0
}
fn default_mem_alert() -> f64 {
80.0
fn default_disk_warning() -> f64 {
75.0
}
fn default_disk_alert() -> f64 {
75.0
fn default_disk_critical() -> f64 {
95.0
}
impl From<PartialServerConfig> for ServerConfig {
@@ -115,9 +139,12 @@ impl From<PartialServerConfig> for ServerConfig {
enabled: value.enabled.unwrap_or(default_enabled()),
auto_prune: value.auto_prune.unwrap_or(default_auto_prune()),
region: value.region.unwrap_or_default(),
cpu_alert: value.cpu_alert.unwrap_or(default_cpu_alert()),
mem_alert: value.mem_alert.unwrap_or(default_mem_alert()),
disk_alert: value.disk_alert.unwrap_or(default_disk_alert()),
cpu_warning: value.cpu_warning.unwrap_or(default_cpu_warning()),
mem_warning: value.mem_warning.unwrap_or(default_mem_warning()),
disk_warning: value.disk_warning.unwrap_or(default_disk_warning()),
cpu_critical: value.cpu_critical.unwrap_or(default_cpu_critical()),
mem_critical: value.mem_critical.unwrap_or(default_mem_critical()),
disk_critical: value.disk_critical.unwrap_or(default_disk_critical()),
to_notify: value.to_notify.unwrap_or_default()
}
}

View File

@@ -2,7 +2,7 @@ use resolver_api::derive::Request;
use serde::{Serialize, Deserialize};
use typeshare::typeshare;
use crate::{entities::server::{Server, PartialServerConfig, stats::{AllSystemStats, SystemInformation, BasicSystemStats, CpuUsage, DiskUsage, NetworkUsage, SystemProcess, SystemComponent}}, MongoDocument};
use crate::{entities::{server::{Server, PartialServerConfig, stats::{AllSystemStats, SystemInformation, BasicSystemStats, CpuUsage, DiskUsage, NetworkUsage, SystemProcess, SystemComponent}, docker_network::DockerNetwork, docker_image::ImageSummary}, update::Update, deployment::BasicContainerInfo}, MongoDocument};
//
@@ -47,6 +47,7 @@ pub struct DeleteServer {
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Server)]
pub struct UpdateServer {
pub id: String,
pub config: PartialServerConfig,
}
@@ -54,7 +55,7 @@ pub struct UpdateServer {
#[typeshare]
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Server)]
#[response(Update)]
pub struct RenameServer {
pub id: String,
pub name: String,
@@ -142,3 +143,48 @@ pub struct GetSystemComponents {
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<DockerNetwork>)]
pub struct GetDockerNetworks {
pub server_id: String,
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Update)]
pub struct PruneDockerNetworks {
pub server_id: String,
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<ImageSummary>)]
pub struct GetDockerImages {
pub server_id: String,
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Update)]
pub struct PruneDockerImages {
pub server_id: String,
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<BasicContainerInfo>)]
pub struct GetDockerContainers {
pub server_id: String,
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Update)]
pub struct PruneDockerContainers {
pub server_id: String,
}

View File

@@ -1,6 +1,6 @@
use async_trait::async_trait;
use monitor_helpers::optional_string;
use monitor_types::entities::update::Log;
use monitor_types::entities::{server::docker_image::ImageSummary, update::Log};
use resolver_api::{derive::Request, Resolve};
use serde::{Deserialize, Serialize};
@@ -32,6 +32,19 @@ impl Resolve<Build> for State {
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<ImageSummary>)]
pub struct GetImageList {}
#[async_trait::async_trait]
impl Resolve<GetImageList> for State {
async fn resolve(&self, _: GetImageList, _: ()) -> anyhow::Result<Vec<ImageSummary>> {
self.docker.list_images().await
}
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Log)]
pub struct PruneImages {}

View File

@@ -2,7 +2,6 @@ use anyhow::{anyhow, Context};
use monitor_helpers::optional_string;
use monitor_types::entities::{
deployment::{BasicContainerInfo, Deployment, DockerContainerStats, TerminationSignal},
server::{docker_image::ImageSummary, docker_network::DockerNetwork},
update::Log,
};
use resolver_api::{derive::Request, Resolve};
@@ -81,32 +80,6 @@ impl Resolve<GetContainerStatsList> for State {
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<DockerNetwork>)]
pub struct GetNetworkList {}
#[async_trait::async_trait]
impl Resolve<GetNetworkList> for State {
async fn resolve(&self, _: GetNetworkList, _: ()) -> anyhow::Result<Vec<DockerNetwork>> {
self.docker.list_networks().await
}
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<ImageSummary>)]
pub struct GetImageList {}
#[async_trait::async_trait]
impl Resolve<GetImageList> for State {
async fn resolve(&self, _: GetImageList, _: ()) -> anyhow::Result<Vec<ImageSummary>> {
self.docker.list_images().await
}
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Log)]
pub struct StartContainer {

View File

@@ -1,5 +1,5 @@
use async_trait::async_trait;
use monitor_types::entities::update::Log;
use monitor_types::entities::{server::docker_network::DockerNetwork, update::Log};
use resolver_api::{derive::Request, Resolve};
use serde::{Deserialize, Serialize};
@@ -7,6 +7,19 @@ use crate::{helpers::docker, state::State};
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Vec<DockerNetwork>)]
pub struct GetNetworkList {}
#[async_trait]
impl Resolve<GetNetworkList> for State {
async fn resolve(&self, _: GetNetworkList, _: ()) -> anyhow::Result<Vec<DockerNetwork>> {
self.docker.list_networks().await
}
}
//
#[derive(Serialize, Deserialize, Debug, Clone, Request)]
#[response(Log)]
pub struct CreateNetwork {