Compare commits

...

4 commits

Author SHA1 Message Date
2c55f5eb54 main: add some logging
All checks were successful
ci / docker-build (push) Successful in 5m25s
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
2024-05-25 00:07:15 +02:00
816480d091 main: removed debug prints
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
2024-05-24 23:54:43 +02:00
dcce9113d1 Proxy: value: handle i64/f64/string
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
2024-05-24 23:54:11 +02:00
0c96891a46 example.yml: add trailing slash
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
2024-05-24 23:53:42 +02:00
4 changed files with 135 additions and 15 deletions

98
Cargo.lock generated
View file

@ -236,6 +236,55 @@ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
] ]
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.2" version = "1.1.2"
@ -349,6 +398,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "colorchoice"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]] [[package]]
name = "convert_case" name = "convert_case"
version = "0.4.0" version = "0.4.0"
@ -451,6 +506,29 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "env_filter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"humantime",
"log",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -686,6 +764,12 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.3.1" version = "1.3.1"
@ -768,6 +852,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.11" version = "1.0.11"
@ -970,7 +1060,9 @@ name = "opentsdb-auth-proxy"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-web", "actix-web",
"env_logger",
"glob-match", "glob-match",
"log",
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
@ -1648,6 +1740,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.15" version = "0.2.15"

View file

@ -5,7 +5,9 @@ edition = "2021"
[dependencies] [dependencies]
actix-web = "4.6.0" actix-web = "4.6.0"
env_logger = "0.11.3"
glob-match = "0.2.1" glob-match = "0.2.1"
log = "0.4.21"
reqwest = "0.12.4" reqwest = "0.12.4"
serde = { version = "1.0.202", features = ["serde_derive"] } serde = { version = "1.0.202", features = ["serde_derive"] }
serde_json = "1.0.117" serde_json = "1.0.117"

View file

@ -16,6 +16,6 @@ clients:
config: config:
opentsdb: opentsdb:
url: http://opentsdb/api url: http://opentsdb/api/
server: server:
port: 8080 port: 8080

View file

@ -1,6 +1,7 @@
use actix_web::http::StatusCode; use actix_web::http::StatusCode;
use actix_web::middleware::Logger; use actix_web::middleware::Logger;
use actix_web::{web, App, HttpResponse, HttpServer, Responder}; use actix_web::{error, web, App, HttpResponse, HttpServer, Responder};
use log::{debug, error, info, log_enabled, Level};
use reqwest::Client; use reqwest::Client;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
@ -19,11 +20,19 @@ struct QSParams {
token: String, token: String,
} }
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
enum OtsdbValue {
String(String),
Integer(i64),
Float(f64),
}
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
struct OtsdbData { struct OtsdbData {
metric: String, metric: String,
value: String, value: OtsdbValue,
timestamp: f64, timestamp: i64,
tags: HashMap<String, String>, tags: HashMap<String, String>,
} }
@ -35,28 +44,33 @@ async fn put_post(
qs: web::Query<QSParams>, qs: web::Query<QSParams>,
body: web::Json<OtsdbData>, body: web::Json<OtsdbData>,
) -> impl Responder { ) -> impl Responder {
println!("Body: {:?}", body);
let authenticated_client = config::try_authenticate_client(&shared.cfg.clients, &qs.token); let authenticated_client = config::try_authenticate_client(&shared.cfg.clients, &qs.token);
if authenticated_client.is_none() { if authenticated_client.is_none() {
return HttpResponse::Unauthorized().body("Unauthorized. Please specify a valid token."); let emsg = format!(
"Unauthorized. Unknown token: {}. Please specify a valid tokne.",
qs.token
);
error!("{}", emsg);
return HttpResponse::Unauthorized().body(emsg);
} }
let client = authenticated_client.unwrap(); let client = authenticated_client.unwrap();
if !client.can_write(&body.metric) { if !client.can_write(&body.metric) {
return HttpResponse::Forbidden().body(format!( let emsg = format!(
"Not allowed to write metric `{}`. Allowed metrics: {}", "Not allowed to write metric `{}`. Allowed metrics: {}",
body.metric, body.metric,
client.metrics.join(", ") client.metrics.join(", ")
)); );
error!("{}", emsg);
return HttpResponse::Forbidden().body(format!("{}", emsg));
} }
println!("Client: {:?}", client);
let post_url = format!("{}put", shared.cfg.config.opentsdb.url); let post_url = format!("{}put", shared.cfg.config.opentsdb.url);
let otsdb_body = serde_json::to_string(&body).unwrap(); let otsdb_body = serde_json::to_string(&body).unwrap();
println!("POST URL: {}", post_url); debug!("POST {} with body: {}", post_url, otsdb_body);
let response = shared let response = shared
.web_client .web_client
@ -70,11 +84,16 @@ async fn put_post(
let status = resp.status(); let status = resp.status();
let body = resp.text().await.unwrap_or_else(|_| "".to_string()); let body = resp.text().await.unwrap_or_else(|_| "".to_string());
debug!("OpenTSDB response {}: {}", status, body);
let sstatus = let sstatus =
StatusCode::from_u16(status.as_u16()).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR); StatusCode::from_u16(status.as_u16()).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
HttpResponse::Ok().status(sstatus).body(body) HttpResponse::Ok().status(sstatus).body(body)
} }
Err(err) => HttpResponse::InternalServerError().body(format!("Error: {}", err)), Err(err) => {
error!("OpenTSDB error: {}", err);
HttpResponse::InternalServerError().body(format!("Proxy error: {}", err))
}
} }
} }
@ -83,7 +102,9 @@ async fn main() -> std::io::Result<()> {
let cfg_file = env::var("CONFIG_FILE").unwrap_or(CONFIG_FILE.to_string()); let cfg_file = env::var("CONFIG_FILE").unwrap_or(CONFIG_FILE.to_string());
let cfg = config::load_config_file(&cfg_file); let cfg = config::load_config_file(&cfg_file);
println!("Config: {:?}", cfg); env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
println!("Loaded config: {:#?}", cfg);
let server_port = cfg.config.server.port.clone(); let server_port = cfg.config.server.port.clone();
let web_client = Client::new(); let web_client = Client::new();
@ -96,11 +117,10 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(move || { HttpServer::new(move || {
App::new() App::new()
.app_data(client_data.clone()) //.client_data.clone()) .app_data(client_data.clone())
.app_data(web::JsonConfig::default().content_type_required(false)) .app_data(web::JsonConfig::default().content_type_required(false))
.wrap(Logger::default()) .wrap(Logger::new("%r %s")) // k8s already logs timestamp
.service(put_post) .service(put_post)
//.route("/put", web::post().to(put_post))
}) })
.bind(format!("[::]:{}", server_port))? .bind(format!("[::]:{}", server_port))?
.run() .run()