Skip to content

Commit 25d0749

Browse files
committed
Add config file option
1 parent 4b9a22a commit 25d0749

11 files changed

+137
-42
lines changed

Cargo.lock

+21-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "nav_data"
3-
version = "0.1.0"
3+
version = "0.1.5"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -25,11 +25,12 @@ bson = "2.8.1"
2525
clap = { version = "4.4.18", features = ["derive"] }
2626
clap_derive = "4.4.7"
2727
futures = "0.3.30"
28+
serde_yaml = "0.9.30"
2829

2930
[dependencies.uuid]
3031
version = "1.7.0"
3132
features = [
3233
"v4", # Lets you generate random UUIDs
3334
"fast-rng", # Use a faster (but still sufficiently random) RNG
3435
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
35-
]
36+
]

Dockerfile

+4-13
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LABEL maintainer="Laurent <laurent@vromman.org>" \
99
org.opencontainers.image.vendor="Laurent Vromman" \
1010
org.opencontainers.image.documentation="https://github.com/leirn/navdata/README.md" \
1111
org.opencontainers.image.licenses="MIT" \
12-
org.opencontainers.image.version="0.1.3" \
12+
org.opencontainers.image.version="0.1.5" \
1313
org.opencontainers.image.url="https://github.com/leirn/navdata/" \
1414
org.opencontainers.image.source="https://github.com/leirn/navdata/" \
1515
org.opencontainers.image.revision=$VCS_REF \
@@ -20,21 +20,12 @@ COPY . /app
2020
RUN apt-get update && apt-get -y install sqlite3
2121
RUN cargo build --release
2222

23-
FROM gcr.io/distroless/cc-debian12
23+
FROM gcr.io/distroless/cc-debian12:lastest
2424

2525
ENV DATABASE_FOLDER=/data
2626

2727
VOLUME "/data"
28-
29-
ENV HOST=0.0.0.0
30-
31-
ENV PORT=8080
32-
33-
ARG DATABASE_PATH=":memory:"
34-
ENV DATABASE_PATH=${DATABASE_PATH}
35-
36-
ARG TOKEN_LIST=""
37-
ENV TOKEN_LIST=${TOKEN_LIST}
28+
VOLUME "/config"
3829

3930
ARG RUST_LOG="warn"
4031
ENV RUST_LOG=${RUST_LOG}
@@ -46,4 +37,4 @@ EXPOSE 8080
4637

4738
COPY --from=build-env /app/target/release/nav_data /
4839
COPY --from=build-env /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6 /usr/lib/x86_64-linux-gnu/libsqlite3.so.0
49-
CMD ["./nav_data"]
40+
CMD ["./nav_data --config /config/config.yaml"]

README.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,24 @@ This data MUST NOT be used to plan real life flights.
2828
- ```GET /airport?search={query}``` : look for an airport based on ```query``` string. Answer first 100 results
2929
- ```GET /airport/{icao}``` : look for an airport based on its ICAO code
3030
- ```GET /navaid?search={query}``` : look for a navaid (VOR, DME, ADF...) based on ```query``` string. Answer first 100 results
31-
- ```GET /navaid/{icao}``` : look for an navaid based on its ICAO code
31+
- ```GET /navaid/{icao}``` : look for an navaid based on its ICAO code
32+
33+
### Config file
34+
35+
Config files must be given for docker as ```/config/config.yaml```.
36+
37+
Format is:
38+
39+
```yaml
40+
http:
41+
host: 127.0.0.1
42+
port: 8080
43+
security:
44+
auth_tokens:
45+
- aaaa
46+
- bbbb
47+
- cccc
48+
database:
49+
backend : MONGODB # can be either SQLITE or MONGODB
50+
path : mongodb://localhost:27017 # Mongo URI if mongo (mandatory. Path to sqlite file if sqlite. If sqlite and no path, memory is used
51+
```

navdata_config.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
http:
2+
host: 127.0.0.1
3+
port: 8080
4+
security:
5+
auth_tokens:
6+
- aaaa
7+
- bbbb
8+
- cccc
9+
database:
10+
backend : MONGODB # can be either SQLITE or MONGODB
11+
path : mongodb://localhost:27017 # Mongo URI if mongo (mandatory. Path to sqlite file if sqlite. If sqlite and no path, memory is used

src/app/config/mod.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use serde::Deserialize;
2+
3+
use super::db::BackendType;
4+
5+
#[derive(Debug, Deserialize, Default)]
6+
pub struct Config {
7+
pub http: HttpConfig,
8+
pub security: SecurityConfig,
9+
pub database: DatabaseConfig,
10+
}
11+
12+
#[derive(Debug, Deserialize, Default)]
13+
pub struct HttpConfig {
14+
pub host: String,
15+
pub port: u16,
16+
}
17+
18+
#[derive(Debug, Deserialize, Default)]
19+
pub struct SecurityConfig {
20+
pub auth_tokens: Vec<String>,
21+
}
22+
23+
#[derive(Debug, Deserialize, Default)]
24+
pub struct DatabaseConfig {
25+
pub backend: BackendType,
26+
pub path: Option<String>,
27+
}

src/app/db/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub mod mongodb;
33
pub mod sqlite;
44
use self::mongodb::MongoDbBackend;
55
use self::sqlite::SqliteBackend;
6+
use crate::app::config::Config;
67
use log::error;
78
use serde::{Deserialize, Serialize};
89
use std::error::Error;
@@ -414,15 +415,17 @@ pub struct Navaid {
414415

415416
pub struct AppState {
416417
pub database: DatabaseBackend,
418+
pub config: Config,
417419
}
418420

419421
pub async fn periodical_update(app_state: web::Data<AppState>) {
420422
let state = app_state.clone();
421423
state.database.periodical_update().await
422424
}
423425

424-
#[derive(Clone, Copy)]
426+
#[derive(Clone, Copy, Debug, Default, Deserialize)]
425427
pub enum BackendType {
428+
#[default]
426429
SQLITE,
427430
MONGODB,
428431
}

src/app/messages.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ pub const ERROR_SQLITE_ACCESS: &str = "Error while accessing SQLite connection";
33
pub const CSV_FORMAT_ERROR: &str = "CSV file does not have the right format";
44

55
// Parameters
6-
pub const PARAM_TOKEN_LIST: &str = "TOKEN_LIST";
76
pub const TOKEN_COOKIE: &str = "navaid_auth_token";
87

98
// HTTP

src/app/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod config;
12
pub mod db;
23
pub mod messages;
34
pub mod navdata;

src/app/security/simple_token.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use super::error::AuthorizationError;
2+
use crate::app::db::AppState;
3+
use crate::app::messages::TOKEN_COOKIE;
24
use actix_web::dev::{forward_ready, Service, ServiceResponse, Transform};
35
use actix_web::{dev::ServiceRequest, Error};
4-
5-
use crate::app::messages::{PARAM_TOKEN_LIST, TOKEN_COOKIE};
6-
use std::env;
76
use std::{
87
future::{ready, Future, Ready},
98
pin::Pin,
@@ -74,22 +73,20 @@ where
7473
let conn_info = req.connection_info().clone();
7574
let real_remote_addr = conn_info.realip_remote_addr().unwrap_or("unknown");
7675

77-
let tokens = env::var(PARAM_TOKEN_LIST);
78-
79-
let success = match tokens {
80-
Ok(tokens) => {
81-
let tokens: Vec<&str> = tokens.split(",").collect();
76+
let app_data = req.app_data::<AppState>().unwrap();
8277

78+
let success = match app_data.config.security.auth_tokens.len() {
79+
// If no token set
80+
0 => true,
81+
_ => {
8382
let token = match req.cookie(TOKEN_COOKIE) {
8483
Some(cookie) => cookie.value().to_owned(),
8584
None => {
8685
return Err(Error::from(AuthorizationError::NoToken).into());
8786
}
8887
};
89-
tokens.len() == 0 || tokens.contains(&token.as_str())
88+
app_data.config.security.auth_tokens.contains(&token)
9089
}
91-
// If not set, bypass auth
92-
Err(_) => true,
9390
};
9491

9592
match success {

src/main.rs

+37-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
mod app;
22
use actix_cors::Cors;
33
use actix_web::{middleware::Logger, web, App, HttpServer};
4+
use app::config::Config;
45
use app::db::{periodical_update, AppState, BackendType, DatabaseBackend};
56
use app::security::simple_token::SimpleToken;
67
use clap::Parser;
8+
use std::path::PathBuf;
79

810
#[derive(Parser, Debug)]
911
#[command(author, version, about, long_about = None)]
@@ -31,6 +33,10 @@ struct Args {
3133
/// loglevel. 0 for error, 1 for warn, 2 for info, 3 for debug
3234
#[arg(short, long, default_value_t = 2)]
3335
loglevel: u8,
36+
37+
/// path to YAML config file
38+
#[arg(short, long)]
39+
config: PathBuf,
3440
}
3541

3642
#[actix_web::main]
@@ -39,21 +45,40 @@ async fn main() -> std::io::Result<()> {
3945

4046
let args = Args::parse();
4147

42-
let host = args.address;
43-
let port = args.port;
48+
let mut config = Config::default();
49+
if args.config.exists() {
50+
let f = std::fs::File::open(args.config).expect("Could not open file.");
51+
config = serde_yaml::from_reader(f).expect("Could not read values.");
52+
} else {
53+
config.http.host = args.address.clone();
54+
config.http.port = args.port;
4455

45-
let backend_type = {
46-
if args.mongodb {
47-
BackendType::MONGODB
48-
} else {
49-
BackendType::SQLITE
50-
}
51-
};
52-
let database_path = args.db_path;
56+
config.database.backend = {
57+
if args.mongodb {
58+
BackendType::MONGODB
59+
} else {
60+
BackendType::SQLITE
61+
}
62+
};
63+
config.database.path = Some(args.db_path.clone());
64+
}
65+
let backend = DatabaseBackend::new(
66+
config.database.backend,
67+
config
68+
.database
69+
.path
70+
.clone()
71+
.unwrap_or(":memory:".to_string()),
72+
)
73+
.await;
5374

54-
let backend = DatabaseBackend::new(backend_type, database_path).await;
75+
let host = config.http.host.clone();
76+
let port = config.http.port;
5577

56-
let app_state = web::Data::new(AppState { database: backend });
78+
let app_state: web::Data<AppState> = web::Data::new(AppState {
79+
database: backend,
80+
config: config,
81+
});
5782

5883
actix_rt::spawn(periodical_update(app_state.clone()));
5984

0 commit comments

Comments
 (0)