start to implement the configuration file and mrproxy integration
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/target/
|
||||
/mdeploy.db
|
||||
/mrdeploy_data/
|
||||
/config/config.toml
|
||||
|
||||
55
Cargo.lock
generated
55
Cargo.lock
generated
@@ -1266,6 +1266,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1623,6 +1624,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
@@ -1847,6 +1857,45 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.10+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
|
||||
dependencies = [
|
||||
"indexmap 2.12.1",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.3"
|
||||
@@ -2257,6 +2306,12 @@ version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
|
||||
@@ -15,6 +15,7 @@ log = "0.4"
|
||||
serde = "*"
|
||||
serde_json = "*"
|
||||
fallible-iterator = "*"
|
||||
toml = "0.9"
|
||||
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
rustflags = [
|
||||
|
||||
7
config/config_template.toml
Normal file
7
config/config_template.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[docker]
|
||||
connection = "http"
|
||||
string = "http://my-custom-docker-server:2735"
|
||||
|
||||
[mrproxy]
|
||||
connection = "tcp"
|
||||
string = "127.0.0.1:25564"
|
||||
102
src/config/mod.rs
Normal file
102
src/config/mod.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use std::{error::Error, fs::read_to_string, io};
|
||||
use toml::Table;
|
||||
|
||||
pub const CONFIG_PATH: &str = "config/config.tom";
|
||||
|
||||
enum DockerConnectionKind {
|
||||
HTTP,
|
||||
HTTP_DEFAULT,
|
||||
UNIX,
|
||||
UNIX_DEFAULT,
|
||||
}
|
||||
|
||||
pub enum MrproxyConnectionKind {
|
||||
TCP,
|
||||
UNIX,
|
||||
}
|
||||
|
||||
pub struct DockerConnectionConfig {
|
||||
connection_kind: DockerConnectionKind,
|
||||
connection_string: Option<String>,
|
||||
}
|
||||
|
||||
pub struct MrproxyConnectionData {
|
||||
pub connection_kind: MrproxyConnectionKind,
|
||||
pub connection_string: String,
|
||||
}
|
||||
|
||||
impl DockerConnectionConfig {
|
||||
pub fn get_config(file_name: &str) -> Result<Self, Box<dyn Error>> {
|
||||
let stored_file = read_to_string(file_name)?.parse::<Table>()?;
|
||||
let connection_kind_string = stored_file["docker"]["connection"].as_str().ok_or(
|
||||
generate_toml_parser_error_in_field("docker connection kind"),
|
||||
)?;
|
||||
|
||||
let connection_kind = match connection_kind_string {
|
||||
"http" => DockerConnectionKind::HTTP,
|
||||
"http_default" => DockerConnectionKind::HTTP_DEFAULT,
|
||||
"unix" => DockerConnectionKind::UNIX,
|
||||
"unix_default" => DockerConnectionKind::UNIX_DEFAULT,
|
||||
_ => {
|
||||
return Err(Box::new(generate_toml_parser_error_in_field(
|
||||
"docker connection kind",
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
let connection_string = match connection_kind {
|
||||
DockerConnectionKind::HTTP | DockerConnectionKind::UNIX => Some(
|
||||
stored_file["docker"]["string"]
|
||||
.as_str()
|
||||
.ok_or(generate_toml_parser_error_in_field(
|
||||
"docker connection string",
|
||||
))?
|
||||
.to_string(),
|
||||
),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
connection_kind,
|
||||
connection_string,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl MrproxyConnectionData {
|
||||
pub fn get_config(file_name: &str) -> Result<Self, Box<dyn Error>> {
|
||||
let stored_file = read_to_string(file_name)?.parse::<Table>()?;
|
||||
let connection_kind_string = stored_file["mrproxy"]["connection"].as_str().ok_or(
|
||||
generate_toml_parser_error_in_field("mrproxy connection kind"),
|
||||
)?;
|
||||
|
||||
let connection_kind = match connection_kind_string {
|
||||
"tcp" => MrproxyConnectionKind::TCP,
|
||||
"unix" => MrproxyConnectionKind::UNIX,
|
||||
_ => {
|
||||
return Err(Box::new(generate_toml_parser_error_in_field(
|
||||
"mrproxy connection kind",
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
let connection_string = stored_file["mrproxy"]["string"]
|
||||
.as_str()
|
||||
.ok_or(generate_toml_parser_error_in_field(
|
||||
"mrproxy connection string",
|
||||
))?
|
||||
.to_string();
|
||||
|
||||
Ok(Self {
|
||||
connection_kind,
|
||||
connection_string,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_toml_parser_error_in_field(field: &str) -> io::Error {
|
||||
io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("Invalid format for config.toml in {} field", field),
|
||||
)
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
use crate::config::{DockerConnectionConfig, MrproxyConnectionData};
|
||||
use crate::database::exposer::MemStorage;
|
||||
use crate::database::instance::Instance;
|
||||
use crate::deploy;
|
||||
use crate::deploy::container::Container;
|
||||
use crate::deploy::container_options::Options;
|
||||
use crate::mcproxy_client::client;
|
||||
use crate::{deploy, mcproxy_client};
|
||||
use bollard::errors::Error;
|
||||
use bollard::Docker;
|
||||
use log::error;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub struct Controller {
|
||||
@@ -13,6 +16,8 @@ pub struct Controller {
|
||||
network: String,
|
||||
storage: Mutex<MemStorage>,
|
||||
started: bool,
|
||||
docker_config: DockerConnectionConfig,
|
||||
mrproxy_config: MrproxyConnectionData,
|
||||
}
|
||||
|
||||
impl Controller {
|
||||
@@ -20,6 +25,8 @@ impl Controller {
|
||||
driver: Docker,
|
||||
network: String,
|
||||
range: String,
|
||||
docker_config: DockerConnectionConfig,
|
||||
mrproxy_config: MrproxyConnectionData,
|
||||
) -> Result<Self, bollard::errors::Error> {
|
||||
deploy::network::Network::new(driver.clone(), network.clone(), range).await?;
|
||||
let cont = Self {
|
||||
@@ -27,6 +34,8 @@ impl Controller {
|
||||
network: network,
|
||||
storage: Mutex::new(MemStorage::new().unwrap()),
|
||||
started: false,
|
||||
docker_config,
|
||||
mrproxy_config,
|
||||
};
|
||||
Ok(cont)
|
||||
}
|
||||
@@ -40,16 +49,31 @@ impl Controller {
|
||||
) -> String {
|
||||
let is_stored = self.storage.lock().unwrap().search_instance(domain.clone());
|
||||
match is_stored {
|
||||
Some(c) => match c.docker_id {
|
||||
Some(c) => {
|
||||
let mut mrcp_controller =
|
||||
mcproxy_client::controller::Controller::new(&self.mrproxy_config).unwrap();
|
||||
_ = mrcp_controller.insert_new_domain(
|
||||
&domain,
|
||||
&ip.unwrap_or(c.get_ip(&self.driver).await.unwrap()),
|
||||
);
|
||||
match c.docker_id {
|
||||
Some(id) => id,
|
||||
None => "Container without docker_id".to_string(),
|
||||
},
|
||||
}
|
||||
}
|
||||
None => {
|
||||
match self
|
||||
.load_container(None, domain.clone(), ip.clone(), image.clone(), ops)
|
||||
.await
|
||||
{
|
||||
Ok(c) => {
|
||||
let mut mrcp_controller =
|
||||
mcproxy_client::controller::Controller::new(&self.mrproxy_config)
|
||||
.unwrap();
|
||||
_ = mrcp_controller.insert_new_domain(
|
||||
&domain,
|
||||
&ip.unwrap_or(c.get_ip(&self.driver).await.unwrap()),
|
||||
);
|
||||
self.storage
|
||||
.try_lock()
|
||||
.unwrap()
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
use crate::{config, controller::Controller};
|
||||
use bollard::Docker;
|
||||
use crate::controller::Controller;
|
||||
|
||||
pub async fn start_docker() -> Controller{
|
||||
pub async fn start_docker() -> Controller {
|
||||
let docker = match Docker::connect_with_local_defaults() {
|
||||
Ok(d) => d,
|
||||
Err(e) => panic!("error:{}",e.to_string()),
|
||||
Err(e) => panic!("error:{}", e.to_string()),
|
||||
};
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
|
||||
let controller = match Controller::new(docker,
|
||||
let controller = match Controller::new(
|
||||
docker,
|
||||
"customnetwork".to_string(),
|
||||
"172.20.0.0/24".to_string()).await {
|
||||
"172.20.0.0/24".to_string(),
|
||||
config::DockerConnectionConfig::get_config(config::CONFIG_PATH).unwrap(),
|
||||
config::MrproxyConnectionData::get_config(config::CONFIG_PATH).unwrap(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(c) => c,
|
||||
Err(e) => panic!("error: {}",e),
|
||||
Err(e) => panic!("error: {}", e),
|
||||
};
|
||||
controller.load_all_instances().await;
|
||||
return controller;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
mod api;
|
||||
mod config;
|
||||
mod controller;
|
||||
mod database;
|
||||
mod deploy;
|
||||
mod mcproxy_client;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() {
|
||||
|
||||
30
src/mcproxy_client/client.rs
Normal file
30
src/mcproxy_client/client.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use std::io::{Read, Result, Write};
|
||||
|
||||
pub fn insert_new_domain(stream: &mut dyn Write, domain: &str, ip: &str) -> Result<()> {
|
||||
_ = stream.write(&[0 as u8]);
|
||||
let domain = domain.as_bytes();
|
||||
let ip = ip.as_bytes();
|
||||
_ = stream.write(&[domain.len() as u8]);
|
||||
_ = stream.write(domain);
|
||||
_ = stream.write(&[ip.len() as u8]);
|
||||
_ = stream.write(ip);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_domain(stream: &mut dyn Write, domain: &str) -> Result<()> {
|
||||
_ = stream.write(&[1 as u8])?;
|
||||
_ = stream.write(&[domain.len() as u8])?;
|
||||
_ = stream.write(domain.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_response(stream: &mut dyn Read) -> Result<u8> {
|
||||
let mut buf: [u8; 1] = [1; 1];
|
||||
_ = stream.read_exact(&mut buf)?;
|
||||
Ok(buf[0])
|
||||
}
|
||||
|
||||
pub fn close_connection(stream: &mut dyn Write) -> Result<()> {
|
||||
_ = stream.write(&[2 as u8])?;
|
||||
Ok(())
|
||||
}
|
||||
78
src/mcproxy_client/controller.rs
Normal file
78
src/mcproxy_client/controller.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
use std::{error::Error, net::TcpStream, os::unix::net::UnixStream};
|
||||
|
||||
use crate::{
|
||||
config::{
|
||||
MrproxyConnectionData,
|
||||
MrproxyConnectionKind::{TCP, UNIX},
|
||||
},
|
||||
mcproxy_client::client,
|
||||
};
|
||||
|
||||
enum KindStream {
|
||||
TCP,
|
||||
UNIX,
|
||||
}
|
||||
|
||||
pub struct Controller {
|
||||
tcp_stream: Option<TcpStream>,
|
||||
unix_stream: Option<UnixStream>,
|
||||
kind_stream: KindStream,
|
||||
}
|
||||
|
||||
impl Controller {
|
||||
pub fn new(conexion_data: &MrproxyConnectionData) -> Result<Self, Box<dyn Error>> {
|
||||
let streams: (Option<TcpStream>, Option<UnixStream>, KindStream) =
|
||||
match conexion_data.connection_kind {
|
||||
TCP => (
|
||||
Some(TcpStream::connect(&conexion_data.connection_string).unwrap()),
|
||||
None,
|
||||
KindStream::TCP,
|
||||
),
|
||||
UNIX => (
|
||||
None,
|
||||
Some(UnixStream::connect(&conexion_data.connection_string).unwrap()),
|
||||
KindStream::UNIX,
|
||||
),
|
||||
};
|
||||
Ok(Self {
|
||||
tcp_stream: streams.0,
|
||||
unix_stream: streams.1,
|
||||
kind_stream: streams.2,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert_new_domain(&mut self, domain: &str, ip: &str) -> Result<u8, std::io::Error> {
|
||||
match self.kind_stream {
|
||||
KindStream::TCP => {
|
||||
_ = client::insert_new_domain(self.tcp_stream.as_mut().unwrap(), domain, ip)?;
|
||||
client::read_response(self.tcp_stream.as_mut().unwrap())
|
||||
}
|
||||
KindStream::UNIX => {
|
||||
_ = client::insert_new_domain(self.unix_stream.as_mut().unwrap(), domain, ip)?;
|
||||
client::read_response(self.unix_stream.as_mut().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_domain(&mut self, domain: &str) -> Result<u8, std::io::Error> {
|
||||
match self.kind_stream {
|
||||
KindStream::TCP => {
|
||||
_ = client::remove_domain(self.tcp_stream.as_mut().unwrap(), domain)?;
|
||||
client::read_response(self.tcp_stream.as_mut().unwrap())
|
||||
}
|
||||
KindStream::UNIX => {
|
||||
_ = client::remove_domain(self.unix_stream.as_mut().unwrap(), domain)?;
|
||||
client::read_response(self.unix_stream.as_mut().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Controller {
|
||||
fn drop(&mut self) {
|
||||
match self.kind_stream {
|
||||
KindStream::TCP => _ = client::close_connection(self.tcp_stream.as_mut().unwrap()),
|
||||
KindStream::UNIX => _ = client::close_connection(self.unix_stream.as_mut().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
2
src/mcproxy_client/mod.rs
Normal file
2
src/mcproxy_client/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod client;
|
||||
pub mod controller;
|
||||
Reference in New Issue
Block a user