Compare commits

..

No commits in common. "4f8df97d1a96019b8fadf608792e08b528b0c148" and "a2a99a1aab8f5c78f343b02957d374ec17bdd1a4" have entirely different histories.

3 changed files with 27 additions and 48 deletions

View File

@ -6,15 +6,12 @@ use axum::Json;
use serde::{Deserialize,Serialize}; use serde::{Deserialize,Serialize};
use crate::*; use crate::*;
use crate::PowerDnsOidcTsigkeyError; use crate::PowerDnsOidcTsigkeyError;
use url::Url;
pub async fn list_keys( pub async fn list_keys(
State(state): State<Arc<AppState>>, State(state): State<Arc<AppState>>,
) -> Result<Json<Vec<TsigKey>>, PowerDnsOidcTsigkeyError> { ) -> Result<Json<Vec<TsigKey>>, PowerDnsOidcTsigkeyError> {
let req = state.http_client.get::<String>( let req = state.http_client.get::<String>((config_cell.get().unwrap().powerdns.url.to_string() + "/servers/localhost/tsigkeys").into())
get_url(state.config.powerdns.url.clone(), "localhost".to_owned(), format!("tsigkeys")) .header("X-API-Key", config_cell.get().unwrap().powerdns.api_token.clone());
)
.header("X-API-Key", state.config.powerdns.api_token.clone());
let response = req let response = req
.send() .send()
.await?; .await?;
@ -33,11 +30,9 @@ pub async fn list_key(
) -> PowerDnsOidcTsigkeyResult<Json<TsigKey>> { ) -> PowerDnsOidcTsigkeyResult<Json<TsigKey>> {
let key: TsigKey = parse_json::<PowerDnsTsigKey>( let key: TsigKey = parse_json::<PowerDnsTsigKey>(
state.http_client.get::<String>( state.http_client.get::<String>(
get_url(state.config.powerdns.url.clone(), (config_cell.get().unwrap().powerdns.url.to_string() + format!("/servers/localhost/tsigkeys/{}", key_id).as_str()).into()
"localhost".to_owned(),
format!("tsigkeys/{}", key_id))
) )
.header("X-API-Key", state.config.powerdns.api_token.clone()) .header("X-API-Key", config_cell.get().unwrap().powerdns.api_token.clone())
.send() .send()
.await? .await?
) )
@ -45,27 +40,11 @@ pub async fn list_key(
.into(); .into();
Ok(axum::Json(key)) Ok(axum::Json(key))
} }
//
pub async fn create_key( //pub async fn create_key(
State(state): State<Arc<AppState>>, // State(state): State<Arc<AppState>>
body: String, //) -> PowerDnsOidcTsigkeyResult<Json<TsigKey>> {}
) -> PowerDnsOidcTsigkeyResult<Json<TsigKey>> { //
let key: TsigKey = parse_json::<PowerDnsTsigKey>(
state.http_client.post(
get_url(state.config.powerdns.url.clone(), "localhost".to_owned(), "tsigkeys".to_owned())
)
.header("X-API-Key", state.config.powerdns.api_token.clone())
.header("Content-Type", "application/json")
.body(body)
.send()
.await?
)
.await?
.into();
Ok(axum::Json(key))
}
//pub async fn modify_key( //pub async fn modify_key(
// Path(key_id): Path<String>, // Path(key_id): Path<String>,
// State(state): State<Arc<AppState>> // State(state): State<Arc<AppState>>
@ -78,9 +57,6 @@ pub async fn create_key(
// //
//} //}
fn get_url(powerdns_url: Url, server: String, endpoint: String) -> String {
format!("{}/servers/{}/{}", powerdns_url.to_string(), server, endpoint).as_str().into()
}
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
pub struct TsigKeyList { pub struct TsigKeyList {

View File

@ -7,8 +7,10 @@ use std::{
fmt::Display, fmt::Display,
}; };
use tokio::sync::OnceCell;
use axum::{ use axum::{
routing::{get, post}, routing::{get},
Router, Router,
http::StatusCode, http::StatusCode,
response::IntoResponse, response::IntoResponse,
@ -123,23 +125,24 @@ async fn parse_json<Out: DeserializeOwned>(res: ReqwestResponse) -> PowerDnsOidc
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct AppState { pub struct AppState {
http_client: Client, http_client: Client,
config: PowerDnsOidcTsigkeyConfig,
} }
static config_cell: OnceCell<PowerDnsOidcTsigkeyConfig> = OnceCell::const_new();
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
match settings::PowerDnsOidcTsigkeyConfig::load("config.yaml") { match settings::PowerDnsOidcTsigkeyConfig::load("config.yaml") {
Ok(config) => { Ok(config) => {
println!("Configuration loaded!"); config_cell.set(config).unwrap();
run(config).await; run().await;
}, },
Err(e) => println!("Failed to load config.yaml: {:?}", e), Err(e) => println!("Failed to load config.yaml: {:?}", e),
}; };
} }
async fn run(config: PowerDnsOidcTsigkeyConfig) { async fn run() {
let addr: SocketAddr = (config.server.bind_address, config.server.port).into(); let addr: SocketAddr = (config_cell.get().unwrap().server.bind_address, config_cell.get().unwrap().server.port).into();
let state = AppState { http_client: reqwest::Client::new(), config: config.clone() }; let state = AppState { http_client: reqwest::Client::new() };
// let router = create_router(state); // let router = create_router(state);
let auth: JwtAuthorizer = JwtAuthorizer::from_oidc(&config_cell.get().unwrap().oidc.issuer.clone().to_string()) let auth: JwtAuthorizer = JwtAuthorizer::from_oidc(&config_cell.get().unwrap().oidc.issuer.clone().to_string())
.validation(Validation::new() .validation(Validation::new()
@ -151,7 +154,7 @@ async fn run(config: PowerDnsOidcTsigkeyConfig) {
let router = Router::new() let router = Router::new()
.route("/api/v1/tsigkeys", get(api::list_keys)) .route("/api/v1/tsigkeys", get(api::list_keys))
.route("/api/v1/tsigkeys/create", post(api::create_key)) // .route("/api/v1/tsigkeys/create", post(api::create_key))
.route("/api/v1/tsigkeys/:keyid", get(api::list_key)) .route("/api/v1/tsigkeys/:keyid", get(api::list_key))
// put(api::create_key).delete(api::delete_key).get(api::list_key)) // put(api::create_key).delete(api::delete_key).get(api::list_key))
.layer(auth.layer().await.unwrap()) .layer(auth.layer().await.unwrap())

View File

@ -4,7 +4,7 @@ use url::Url;
use serde::{Deserialize}; use serde::{Deserialize};
use config::{Config, ConfigError, Environment, File}; use config::{Config, ConfigError, Environment, File};
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct PowerDnsOidcTsigkeyConfig { pub struct PowerDnsOidcTsigkeyConfig {
/// OIDC Provider /// OIDC Provider
pub oidc: OidcConfig, pub oidc: OidcConfig,
@ -16,7 +16,7 @@ pub struct PowerDnsOidcTsigkeyConfig {
pub server: ServerConfig, pub server: ServerConfig,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct PowerDnsConfig { pub struct PowerDnsConfig {
/// URL where PowerDNS API can be reached /// URL where PowerDNS API can be reached
pub url: Url, pub url: Url,
@ -24,13 +24,13 @@ pub struct PowerDnsConfig {
pub api_token: String, pub api_token: String,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct LogConfig { pub struct LogConfig {
/// The log level /// The log level
pub level: String, pub level: String,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct ServerConfig { pub struct ServerConfig {
/// IpAddress to listen on /// IpAddress to listen on
pub bind_address: IpAddr, pub bind_address: IpAddr,
@ -40,12 +40,12 @@ pub struct ServerConfig {
pub tls: ServerTlsConfig, pub tls: ServerTlsConfig,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct ServerTlsConfig { pub struct ServerTlsConfig {
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct OidcConfig { pub struct OidcConfig {
pub issuer: Url, pub issuer: Url,
pub client_id: String, pub client_id: String,
@ -55,7 +55,7 @@ pub struct OidcConfig {
pub validation: OidcValidationConfig, pub validation: OidcValidationConfig,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize)]
pub struct OidcValidationConfig { pub struct OidcValidationConfig {
pub issuer: Vec<Url>, pub issuer: Vec<Url>,
pub audience: Vec<String>, pub audience: Vec<String>,