add dns support
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::api::error::ReturnedError;
|
||||
use crate::config::{
|
||||
docker::DockerConnectionConfig, mrproxy::MrproxyConnectionConfig, server::ServerConfig,
|
||||
CONFIG_PATH,
|
||||
@@ -5,8 +9,8 @@ use crate::config::{
|
||||
use crate::controller::Controller;
|
||||
use crate::deploy::container_options::Options;
|
||||
use crate::deploy::starter;
|
||||
use crate::{api::error::ReturnedError, config};
|
||||
use actix_web::{delete, get, patch, put, web, App, HttpServer, Responder};
|
||||
use dns_manager::ServerZonesConnection;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -57,7 +61,7 @@ async fn delete_container(
|
||||
controller: web::Data<Controller>,
|
||||
params: web::Query<ConainerStopParams>,
|
||||
) -> Result<String, ReturnedError> {
|
||||
match controller.delete_container(params.name.clone()).await {
|
||||
match controller.delete_container_and_unbind(¶ms.name).await {
|
||||
Ok(response) => Ok(response),
|
||||
Err(e) => Err(ReturnedError {
|
||||
name: e.to_string(),
|
||||
@@ -77,12 +81,14 @@ async fn get_ip(
|
||||
}
|
||||
|
||||
pub async fn start() -> std::io::Result<()> {
|
||||
let server_config = ServerConfig::get_config(CONFIG_PATH).unwrap();
|
||||
let controller = starter::start_docker(
|
||||
DockerConnectionConfig::get_config(CONFIG_PATH).unwrap(),
|
||||
MrproxyConnectionConfig::get_config(config::CONFIG_PATH).unwrap(),
|
||||
MrproxyConnectionConfig::get_config(CONFIG_PATH).unwrap(),
|
||||
ServerZonesConnection::get_config(CONFIG_PATH).unwrap(),
|
||||
Ipv4Addr::from_str(&server_config.pub_addr).unwrap(),
|
||||
)
|
||||
.await;
|
||||
let server_config = ServerConfig::get_config(CONFIG_PATH).unwrap();
|
||||
let data = web::Data::new(controller);
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
@@ -93,7 +99,7 @@ pub async fn start() -> std::io::Result<()> {
|
||||
.service(delete_container)
|
||||
.service(get_ip)
|
||||
})
|
||||
.bind((server_config.addr, server_config.port))?
|
||||
.bind((server_config.linstening_addr, server_config.port))?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -3,22 +3,34 @@ use std::{error::Error, fs::read_to_string};
|
||||
use toml::Table;
|
||||
|
||||
pub struct ServerConfig {
|
||||
pub addr: String,
|
||||
pub pub_addr: String,
|
||||
pub linstening_addr: String,
|
||||
pub port: u16,
|
||||
}
|
||||
|
||||
impl ServerConfig {
|
||||
pub fn get_config(file_name: &str) -> Result<Self, Box<dyn Error>> {
|
||||
let stored_file = read_to_string(file_name)?.parse::<Table>()?;
|
||||
let addr = stored_file["server"]["addr"]
|
||||
let pub_addr = stored_file["server"]["public_addr"]
|
||||
.as_str()
|
||||
.ok_or(generate_toml_parser_error_in_field("server addr"))?
|
||||
.ok_or(generate_toml_parser_error_in_field("server public address"))?
|
||||
.to_string();
|
||||
|
||||
let linstening_addr = stored_file["server"]["listening_addr"]
|
||||
.as_str()
|
||||
.ok_or(generate_toml_parser_error_in_field(
|
||||
"server listening address",
|
||||
))?
|
||||
.to_string();
|
||||
|
||||
let port = stored_file["server"]["port"]
|
||||
.as_integer()
|
||||
.ok_or(generate_toml_parser_error_in_field("server port"))? as u16;
|
||||
|
||||
Ok(Self { addr, port })
|
||||
Ok(Self {
|
||||
pub_addr,
|
||||
linstening_addr,
|
||||
port,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::config::{docker::DockerConnectionConfig, mrproxy::MrproxyConnectionConfig};
|
||||
use crate::config::mrproxy::MrproxyConnectionConfig;
|
||||
use crate::database::exposer::MemStorage;
|
||||
use crate::database::instance::Instance;
|
||||
use crate::deploy::container::Container;
|
||||
@@ -6,34 +6,39 @@ use crate::deploy::container_options::Options;
|
||||
use crate::{deploy, mcproxy_client};
|
||||
use bollard::errors::Error;
|
||||
use bollard::Docker;
|
||||
use log::error;
|
||||
use dns_manager::{DnsManager, ServerZonesConnection};
|
||||
use log::{error, warn};
|
||||
use std::error::Error as GenericError;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub struct Controller {
|
||||
driver: Docker,
|
||||
pub_addr: Ipv4Addr,
|
||||
network: String,
|
||||
storage: Mutex<MemStorage>,
|
||||
started: bool,
|
||||
docker_config: DockerConnectionConfig,
|
||||
dns_manager: DnsManager,
|
||||
mrproxy_config: MrproxyConnectionConfig,
|
||||
}
|
||||
|
||||
impl Controller {
|
||||
pub async fn new(
|
||||
driver: Docker,
|
||||
pub_addr: Ipv4Addr,
|
||||
network: String,
|
||||
range: String,
|
||||
docker_config: DockerConnectionConfig,
|
||||
dns_config: ServerZonesConnection,
|
||||
mrproxy_config: MrproxyConnectionConfig,
|
||||
) -> Result<Self, bollard::errors::Error> {
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
deploy::network::Network::new(driver.clone(), network.clone(), range).await?;
|
||||
let cont = Self {
|
||||
driver: driver,
|
||||
pub_addr,
|
||||
network: network,
|
||||
storage: Mutex::new(MemStorage::new().unwrap()),
|
||||
started: false,
|
||||
docker_config,
|
||||
dns_manager: DnsManager::new(dns_config)?,
|
||||
mrproxy_config,
|
||||
};
|
||||
Ok(cont)
|
||||
@@ -83,41 +88,39 @@ impl Controller {
|
||||
.load_container(docker_id, domain.clone(), ip.clone(), image, ops)
|
||||
.await
|
||||
{
|
||||
Ok(c) => {
|
||||
match self
|
||||
.bind_container_in_proxy(domain.clone(), ip, c.clone())
|
||||
.await
|
||||
{
|
||||
Ok(_) => Ok(c),
|
||||
Err(e) => {
|
||||
error!("failed in the bind process with the proxy, deleting the container");
|
||||
self.delete_container(domain).await?;
|
||||
return Err(e);
|
||||
}
|
||||
Ok(c) => match self.bind_container_in_proxy(&domain, ip, &c).await {
|
||||
Ok(_) => {
|
||||
self.add_domain_to_dns(&domain).await?;
|
||||
Ok(c)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("failed in the bind process with the proxy, deleting the container");
|
||||
self.delete_container_and_unbind(&domain).await?;
|
||||
return Err(e);
|
||||
}
|
||||
},
|
||||
Err(e) => return Err(Box::new(e)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn bind_container_in_proxy(
|
||||
&self,
|
||||
domain: String,
|
||||
domain: &str,
|
||||
ip: Option<String>,
|
||||
container: Container,
|
||||
container: &Container,
|
||||
) -> Result<(), Box<dyn GenericError>> {
|
||||
let ip_final = ip.unwrap_or(container.get_ip(&self.driver).await?);
|
||||
log::debug!("ip binded: {}", ip_final);
|
||||
let mut mrcp_controller =
|
||||
mcproxy_client::controller::Controller::new(&self.mrproxy_config)?;
|
||||
mrcp_controller.insert_new_domain(&domain, &ip_final)?;
|
||||
mrcp_controller.insert_new_domain(&self.dns_manager.get_full_domain(domain), &ip_final)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn unbind_container_in_proxy(&self, domain: &str) -> Result<(), Box<dyn GenericError>> {
|
||||
let mut mrcp_controller =
|
||||
mcproxy_client::controller::Controller::new(&self.mrproxy_config)?;
|
||||
mrcp_controller.remove_domain(&domain)?;
|
||||
mrcp_controller.remove_domain(&self.dns_manager.get_full_domain(domain))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -171,6 +174,7 @@ impl Controller {
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn is_started(&self) -> bool {
|
||||
self.started
|
||||
}
|
||||
@@ -217,11 +221,21 @@ impl Controller {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_container(&self, domain: String) -> Result<String, Box<dyn GenericError>> {
|
||||
pub async fn delete_container_and_unbind(
|
||||
&self,
|
||||
domain: &str,
|
||||
) -> Result<String, Box<dyn GenericError>> {
|
||||
match self.storage.lock().unwrap().remove_instance(&domain) {
|
||||
Some(data) => match data.1 {
|
||||
Some(c) => {
|
||||
self.unbind_container_in_proxy(&domain).await?;
|
||||
let r_unbind = self.unbind_container_in_proxy(&domain).await;
|
||||
if r_unbind.is_err() {
|
||||
warn!("Error unbinding container {}", domain);
|
||||
}
|
||||
let r_del_domain = self.del_domain_to_dns(domain).await;
|
||||
if r_del_domain.is_err() {
|
||||
warn!("Error deleting domain {} from dns", domain);
|
||||
}
|
||||
self.prune_given_container(c).await
|
||||
}
|
||||
None => Ok(data.0.docker_id),
|
||||
@@ -242,4 +256,14 @@ impl Controller {
|
||||
.unwrap();
|
||||
container.get_ip(&self.driver).await
|
||||
}
|
||||
|
||||
pub async fn add_domain_to_dns(&self, domain: &str) -> Result<(), Box<dyn GenericError>> {
|
||||
self.dns_manager.add_domain(domain, self.pub_addr).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn del_domain_to_dns(&self, domain: &str) -> Result<(), Box<dyn GenericError>> {
|
||||
self.dns_manager.del_domain(domain).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ impl InstanceStorage {
|
||||
Ok(rows.next()?.unwrap().get::<_, String>(0)?)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn get_instance_id(&self, domain: &str) -> Result<Option<i64>> {
|
||||
let mut stmt = self
|
||||
.con
|
||||
|
||||
@@ -7,5 +7,6 @@ pub struct Instance {
|
||||
pub ip: Option<String>,
|
||||
pub domain: String,
|
||||
pub image: i64,
|
||||
#[allow(dead_code)]
|
||||
pub ops: Options,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ pub struct Container {
|
||||
pub image: String,
|
||||
pub net: String,
|
||||
pub docker_id: Option<String>,
|
||||
#[allow(dead_code)]
|
||||
pub database_id: Option<i64>,
|
||||
pub ops: Options,
|
||||
}
|
||||
|
||||
@@ -3,18 +3,12 @@ use bollard::models::{Ipam, IpamConfig, NetworkCreateRequest};
|
||||
use bollard::query_parameters::ListNetworksOptions;
|
||||
use std::collections::hash_map::HashMap;
|
||||
|
||||
pub struct Network {
|
||||
name: String,
|
||||
range: String,
|
||||
}
|
||||
pub struct Network {}
|
||||
|
||||
impl Network {
|
||||
pub async fn new(docker: bollard::Docker, name: String, range: String) -> Result<Self, Error> {
|
||||
if Self::check_network(docker.clone(), name.clone()).await {
|
||||
Ok(Network {
|
||||
name: name,
|
||||
range: range,
|
||||
})
|
||||
Ok(Network {})
|
||||
} else {
|
||||
Self::create_network(docker, name, range).await
|
||||
}
|
||||
@@ -54,10 +48,7 @@ impl Network {
|
||||
..Default::default()
|
||||
};
|
||||
match docker.create_network(create_network_options).await {
|
||||
Ok(_n) => Ok(Network {
|
||||
name: name,
|
||||
range: range,
|
||||
}),
|
||||
Ok(_n) => Ok(Self {}),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use crate::{
|
||||
config::{
|
||||
docker::DockerConnectionConfig,
|
||||
@@ -7,10 +9,13 @@ use crate::{
|
||||
controller::Controller,
|
||||
};
|
||||
use bollard::{errors::Error, ClientVersion, Docker};
|
||||
use dns_manager::ServerZonesConnection;
|
||||
|
||||
pub async fn start_docker(
|
||||
docker_config: DockerConnectionConfig,
|
||||
mrproxy_config: MrproxyConnectionConfig,
|
||||
dns_config: ServerZonesConnection,
|
||||
pub_addr: Ipv4Addr,
|
||||
) -> Controller {
|
||||
let docker = match generate_docker_connection(&docker_config) {
|
||||
Ok(d) => d,
|
||||
@@ -19,9 +24,10 @@ pub async fn start_docker(
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
|
||||
let controller = match Controller::new(
|
||||
docker,
|
||||
pub_addr,
|
||||
docker_config.network_name.clone(),
|
||||
docker_config.network_addr.clone(),
|
||||
docker_config,
|
||||
dns_config,
|
||||
mrproxy_config,
|
||||
)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user