129 lines
3.8 KiB
Rust
129 lines
3.8 KiB
Rust
use std::net::IpAddr;
|
|
use std::process::exit;
|
|
|
|
use clap::{Parser, Subcommand};
|
|
use rocket::{Rocket, Build};
|
|
use rocket::fairing::AdHoc;
|
|
use rocket::fs::FileServer;
|
|
use figment::Figment;
|
|
|
|
use crate::config::Config;
|
|
use crate::routes::api;
|
|
use crate::routes::ui;
|
|
use crate::{DbConn, get_db_conn};
|
|
use crate::cli::NomiloCommand;
|
|
use crate::template::TemplateState;
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum ServerCommand {
|
|
/// Run web server
|
|
Run(RunServerCommand),
|
|
/// Run database migrations and exit
|
|
Migrate(MigrateCommand),
|
|
}
|
|
|
|
#[derive(Parser)]
|
|
pub struct RunServerCommand {
|
|
#[clap(long = "--address", short = 'a')]
|
|
/// Address to serve application on, override both configuration and environment values
|
|
address: Option<IpAddr>,
|
|
#[clap(long = "--port", short = 'p')]
|
|
/// Port to serve application on, override both configuration and environment values
|
|
port: Option<u16>,
|
|
}
|
|
|
|
#[derive(Parser)]
|
|
pub struct MigrateCommand;
|
|
|
|
|
|
impl NomiloCommand for ServerCommand {
|
|
fn run(self, figment: Figment, app_config: Config) {
|
|
match self {
|
|
ServerCommand::Run(sub) => sub.run(figment, app_config),
|
|
ServerCommand::Migrate(sub) => sub.run(figment, app_config),
|
|
};
|
|
}
|
|
}
|
|
|
|
fn run_migrations(conn: &diesel::SqliteConnection) -> Result<(), diesel_migrations::RunMigrationsError> {
|
|
embed_migrations!("migrations");
|
|
embedded_migrations::run(conn)
|
|
}
|
|
|
|
|
|
async fn run_migrations_fairing(rocket: Rocket<Build>) -> Rocket<Build> {
|
|
embed_migrations!("migrations");
|
|
|
|
let conn = match DbConn::get_one(&rocket).await {
|
|
Some(c) => c,
|
|
None => {
|
|
error!("Could not get a database connection");
|
|
exit(1);
|
|
}
|
|
};
|
|
|
|
if let Err(e) = conn.run(|c| run_migrations(&c)).await {
|
|
error!("Error running migrations: {}", e);
|
|
exit(1);
|
|
}
|
|
|
|
rocket
|
|
|
|
}
|
|
|
|
impl NomiloCommand for RunServerCommand {
|
|
fn run(self, mut figment: Figment, app_config: Config) {
|
|
rocket::async_main(async move {
|
|
if let Some(address) = self.address {
|
|
figment = figment.merge(("address", address));
|
|
}
|
|
if let Some(port) = self.port {
|
|
figment = figment.merge(("port", port));
|
|
}
|
|
let template_state = TemplateState::new(&app_config.web_app.templates_directory);
|
|
let static_files = FileServer::from(&app_config.web_app.static_files);
|
|
|
|
let _res = rocket::custom(figment)
|
|
.manage(app_config)
|
|
.manage(template_state)
|
|
.attach(DbConn::fairing())
|
|
.attach(AdHoc::on_ignite("Database migration", run_migrations_fairing))
|
|
.mount("/api/v1", routes![
|
|
api::get_zone_records,
|
|
api::create_zone_records,
|
|
api::update_zone_records,
|
|
api::delete_zone_records,
|
|
api::get_zones,
|
|
api::create_zone,
|
|
api::add_member_to_zone,
|
|
api::create_auth_token,
|
|
api::create_user,
|
|
])
|
|
.mount("/", routes![
|
|
ui::get_login_page,
|
|
ui::post_login_page,
|
|
ui::get_zones_page,
|
|
ui::get_zone_records_page,
|
|
ui::get_create_zone_page,
|
|
ui::post_create_zone_page,
|
|
])
|
|
.mount("/", static_files)
|
|
.launch().await;
|
|
});
|
|
}
|
|
}
|
|
|
|
impl NomiloCommand for MigrateCommand {
|
|
fn run(self, figment: Figment, _app_config: Config) {
|
|
let conn = get_db_conn(&figment);
|
|
|
|
match run_migrations(&conn) {
|
|
Ok(_) => println!("Migrations ran successfully"),
|
|
Err(e) => {
|
|
error!("Error running migrations: {}", e);
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|