use async_trait::async_trait;
use bollard::Docker;
use bollard::models::{NetworkConnectRequest, NetworkDisconnectRequest};
use ironflow_core::error::OperationError;
use ironflow_core::operation::{Operation, OperationContext, TypedOperation};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::containers::DockerRef;
use crate::helpers::{docker_error, to_value};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkConnectOutput {
pub network: String,
pub container: String,
}
pub struct NetworkConnect {
docker: Docker,
network: String,
container: String,
}
impl NetworkConnect {
pub fn new(
client: impl Into<DockerRef>,
network: impl Into<String>,
container: impl Into<String>,
) -> Self {
Self {
docker: client.into().0,
network: network.into(),
container: container.into(),
}
}
pub async fn run(
&self,
_ctx: &OperationContext,
) -> Result<NetworkConnectOutput, OperationError> {
let request = NetworkConnectRequest {
container: self.container.clone(),
..Default::default()
};
self.docker
.connect_network(&self.network, request)
.await
.map_err(docker_error)?;
Ok(NetworkConnectOutput {
network: self.network.clone(),
container: self.container.clone(),
})
}
}
#[async_trait]
impl Operation for NetworkConnect {
fn kind(&self) -> &str {
"docker"
}
async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
to_value(&self.run(ctx).await?)
}
fn input(&self) -> Option<Value> {
Some(serde_json::json!({
"operation": "network_connect",
"network": self.network,
"container": self.container,
}))
}
}
impl TypedOperation for NetworkConnect {
type Output = NetworkConnectOutput;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkDisconnectOutput {
pub network: String,
pub container: String,
}
pub struct NetworkDisconnect {
docker: Docker,
network: String,
container: String,
}
impl NetworkDisconnect {
pub fn new(
client: impl Into<DockerRef>,
network: impl Into<String>,
container: impl Into<String>,
) -> Self {
Self {
docker: client.into().0,
network: network.into(),
container: container.into(),
}
}
pub async fn run(
&self,
_ctx: &OperationContext,
) -> Result<NetworkDisconnectOutput, OperationError> {
let request = NetworkDisconnectRequest {
container: self.container.clone(),
force: Some(false),
};
self.docker
.disconnect_network(&self.network, request)
.await
.map_err(docker_error)?;
Ok(NetworkDisconnectOutput {
network: self.network.clone(),
container: self.container.clone(),
})
}
}
#[async_trait]
impl Operation for NetworkDisconnect {
fn kind(&self) -> &str {
"docker"
}
async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
to_value(&self.run(ctx).await?)
}
fn input(&self) -> Option<Value> {
Some(serde_json::json!({
"operation": "network_disconnect",
"network": self.network,
"container": self.container,
}))
}
}
impl TypedOperation for NetworkDisconnect {
type Output = NetworkDisconnectOutput;
}