add migrate command to cli
This commit is contained in:
parent
c32c02a5ac
commit
07768a9322
6 changed files with 121 additions and 67 deletions
|
@ -9,6 +9,7 @@ from nomilo_client.models import (
|
||||||
RecordTypeTXT,
|
RecordTypeTXT,
|
||||||
RecordList,
|
RecordList,
|
||||||
UpdateRecordsRequest,
|
UpdateRecordsRequest,
|
||||||
|
CreateZoneRequest,
|
||||||
)
|
)
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pub mod serve;
|
pub mod server;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
@ -6,7 +6,7 @@ use figment::Figment;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
|
||||||
use serve::ServeCommand;
|
use server::ServerCommand;
|
||||||
use user::UserCommand;
|
use user::UserCommand;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -19,8 +19,9 @@ pub struct NomiloCli {
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
/// Lauch web server
|
/// Manage web server
|
||||||
Serve(ServeCommand),
|
#[clap(subcommand)]
|
||||||
|
Server(ServerCommand),
|
||||||
/// Manage users
|
/// Manage users
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
User(UserCommand)
|
User(UserCommand)
|
||||||
|
@ -34,7 +35,7 @@ pub trait NomiloCommand {
|
||||||
impl NomiloCommand for NomiloCli {
|
impl NomiloCommand for NomiloCli {
|
||||||
fn run(self, figment: Figment, app_config: Config) {
|
fn run(self, figment: Figment, app_config: Config) {
|
||||||
match self.command {
|
match self.command {
|
||||||
Command::Serve(sub) => sub.run(figment, app_config),
|
Command::Server(sub) => sub.run(figment, app_config),
|
||||||
Command::User(sub) => sub.run(figment, app_config),
|
Command::User(sub) => sub.run(figment, app_config),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
use clap::Parser;
|
|
||||||
use rocket::{Rocket, Build};
|
|
||||||
use rocket::fairing::AdHoc;
|
|
||||||
use figment::Figment;
|
|
||||||
|
|
||||||
use crate::config::Config;
|
|
||||||
use crate::routes::users::*;
|
|
||||||
use crate::routes::zones::*;
|
|
||||||
use crate::{DbConn};
|
|
||||||
use crate::cli::NomiloCommand;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
pub struct ServeCommand;
|
|
||||||
|
|
||||||
async fn run_migrations(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| embedded_migrations::run(c)).await {
|
|
||||||
error!("Error running migrations: {}", e);
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
rocket
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NomiloCommand for ServeCommand {
|
|
||||||
fn run(self, figment: Figment, app_config: Config) {
|
|
||||||
rocket::async_main(async move {
|
|
||||||
let _res = rocket::custom(figment)
|
|
||||||
.manage(app_config)
|
|
||||||
.attach(DbConn::fairing())
|
|
||||||
.attach(AdHoc::on_ignite("Database migration", run_migrations))
|
|
||||||
.mount("/api/v1", routes![
|
|
||||||
get_zone_records,
|
|
||||||
create_zone_records,
|
|
||||||
update_zone_records,
|
|
||||||
delete_zone_records,
|
|
||||||
get_zones,
|
|
||||||
create_zone,
|
|
||||||
add_member_to_zone,
|
|
||||||
create_auth_token,
|
|
||||||
create_user,
|
|
||||||
])
|
|
||||||
.launch().await;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
113
src/cli/server.rs
Normal file
113
src/cli/server.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
use std::net::IpAddr;
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use rocket::{Rocket, Build};
|
||||||
|
use rocket::fairing::AdHoc;
|
||||||
|
use figment::Figment;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::routes::users::*;
|
||||||
|
use crate::routes::zones::*;
|
||||||
|
use crate::{DbConn, get_db_conn};
|
||||||
|
use crate::cli::NomiloCommand;
|
||||||
|
|
||||||
|
#[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 _res = rocket::custom(figment)
|
||||||
|
.manage(app_config)
|
||||||
|
.attach(DbConn::fairing())
|
||||||
|
.attach(AdHoc::on_ignite("Database migration", run_migrations_fairing))
|
||||||
|
.mount("/api/v1", routes![
|
||||||
|
get_zone_records,
|
||||||
|
create_zone_records,
|
||||||
|
update_zone_records,
|
||||||
|
delete_zone_records,
|
||||||
|
get_zones,
|
||||||
|
create_zone,
|
||||||
|
add_member_to_zone,
|
||||||
|
create_auth_token,
|
||||||
|
create_user,
|
||||||
|
])
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,6 @@ impl NomiloCommand for UserCommand {
|
||||||
|
|
||||||
impl NomiloCommand for AddUserCommand {
|
impl NomiloCommand for AddUserCommand {
|
||||||
fn run(self, figment: Figment, _app_config: Config) {
|
fn run(self, figment: Figment, _app_config: Config) {
|
||||||
|
|
||||||
let res = LocalUser::create_user(&get_db_conn(&figment), CreateUserRequest {
|
let res = LocalUser::create_user(&get_db_conn(&figment), CreateUserRequest {
|
||||||
username: self.name,
|
username: self.name,
|
||||||
email: self.email,
|
email: self.email,
|
||||||
|
|
|
@ -26,7 +26,6 @@ pub struct DbConn(diesel::SqliteConnection);
|
||||||
|
|
||||||
|
|
||||||
pub fn get_db_conn(figment: &Figment) -> diesel::SqliteConnection {
|
pub fn get_db_conn(figment: &Figment) -> diesel::SqliteConnection {
|
||||||
|
|
||||||
let url = match figment.focus("databases.sqlite").extract_inner::<String>("url") {
|
let url = match figment.focus("databases.sqlite").extract_inner::<String>("url") {
|
||||||
Ok(url) => url,
|
Ok(url) => url,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
Loading…
Reference in a new issue