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/
|
/target/
|
||||||
/mdeploy.db
|
/mdeploy.db
|
||||||
/mrdeploy_data/
|
/mrdeploy_data/
|
||||||
|
/config/config.toml
|
||||||
|
|||||||
55
Cargo.lock
generated
55
Cargo.lock
generated
@@ -1266,6 +1266,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1623,6 +1624,15 @@ dependencies = [
|
|||||||
"syn",
|
"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]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -1847,6 +1857,45 @@ dependencies = [
|
|||||||
"tokio",
|
"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]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -2257,6 +2306,12 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wit-bindgen"
|
||||||
version = "0.46.0"
|
version = "0.46.0"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ log = "0.4"
|
|||||||
serde = "*"
|
serde = "*"
|
||||||
serde_json = "*"
|
serde_json = "*"
|
||||||
fallible-iterator = "*"
|
fallible-iterator = "*"
|
||||||
|
toml = "0.9"
|
||||||
|
|
||||||
[target.x86_64-unknown-linux-gnu]
|
[target.x86_64-unknown-linux-gnu]
|
||||||
rustflags = [
|
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::exposer::MemStorage;
|
||||||
use crate::database::instance::Instance;
|
use crate::database::instance::Instance;
|
||||||
use crate::deploy;
|
|
||||||
use crate::deploy::container::Container;
|
use crate::deploy::container::Container;
|
||||||
use crate::deploy::container_options::Options;
|
use crate::deploy::container_options::Options;
|
||||||
|
use crate::mcproxy_client::client;
|
||||||
|
use crate::{deploy, mcproxy_client};
|
||||||
use bollard::errors::Error;
|
use bollard::errors::Error;
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
pub struct Controller {
|
pub struct Controller {
|
||||||
@@ -13,6 +16,8 @@ pub struct Controller {
|
|||||||
network: String,
|
network: String,
|
||||||
storage: Mutex<MemStorage>,
|
storage: Mutex<MemStorage>,
|
||||||
started: bool,
|
started: bool,
|
||||||
|
docker_config: DockerConnectionConfig,
|
||||||
|
mrproxy_config: MrproxyConnectionData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controller {
|
impl Controller {
|
||||||
@@ -20,6 +25,8 @@ impl Controller {
|
|||||||
driver: Docker,
|
driver: Docker,
|
||||||
network: String,
|
network: String,
|
||||||
range: String,
|
range: String,
|
||||||
|
docker_config: DockerConnectionConfig,
|
||||||
|
mrproxy_config: MrproxyConnectionData,
|
||||||
) -> Result<Self, bollard::errors::Error> {
|
) -> Result<Self, bollard::errors::Error> {
|
||||||
deploy::network::Network::new(driver.clone(), network.clone(), range).await?;
|
deploy::network::Network::new(driver.clone(), network.clone(), range).await?;
|
||||||
let cont = Self {
|
let cont = Self {
|
||||||
@@ -27,6 +34,8 @@ impl Controller {
|
|||||||
network: network,
|
network: network,
|
||||||
storage: Mutex::new(MemStorage::new().unwrap()),
|
storage: Mutex::new(MemStorage::new().unwrap()),
|
||||||
started: false,
|
started: false,
|
||||||
|
docker_config,
|
||||||
|
mrproxy_config,
|
||||||
};
|
};
|
||||||
Ok(cont)
|
Ok(cont)
|
||||||
}
|
}
|
||||||
@@ -40,16 +49,31 @@ impl Controller {
|
|||||||
) -> String {
|
) -> String {
|
||||||
let is_stored = self.storage.lock().unwrap().search_instance(domain.clone());
|
let is_stored = self.storage.lock().unwrap().search_instance(domain.clone());
|
||||||
match is_stored {
|
match is_stored {
|
||||||
Some(c) => match c.docker_id {
|
Some(c) => {
|
||||||
Some(id) => id,
|
let mut mrcp_controller =
|
||||||
None => "Container without docker_id".to_string(),
|
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 => {
|
None => {
|
||||||
match self
|
match self
|
||||||
.load_container(None, domain.clone(), ip.clone(), image.clone(), ops)
|
.load_container(None, domain.clone(), ip.clone(), image.clone(), ops)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(c) => {
|
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
|
self.storage
|
||||||
.try_lock()
|
.try_lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
|
use crate::{config, controller::Controller};
|
||||||
use bollard::Docker;
|
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() {
|
let docker = match Docker::connect_with_local_defaults() {
|
||||||
Ok(d) => d,
|
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"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
|
||||||
let controller = match Controller::new(docker,
|
let controller = match Controller::new(
|
||||||
"customnetwork".to_string(),
|
docker,
|
||||||
"172.20.0.0/24".to_string()).await {
|
"customnetwork".to_string(),
|
||||||
Ok(c) => c,
|
"172.20.0.0/24".to_string(),
|
||||||
Err(e) => panic!("error: {}",e),
|
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),
|
||||||
|
};
|
||||||
controller.load_all_instances().await;
|
controller.load_all_instances().await;
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
mod api;
|
mod api;
|
||||||
|
mod config;
|
||||||
mod controller;
|
mod controller;
|
||||||
mod database;
|
mod database;
|
||||||
mod deploy;
|
mod deploy;
|
||||||
|
mod mcproxy_client;
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn 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