mirror of
https://github.com/house-of-vanity/k8s-secrets.git
synced 2026-02-04 01:37:57 +00:00
Added query params to get values in plain text
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -112,6 +112,8 @@ dependencies = [
|
||||
"humansize",
|
||||
"num-traits",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "secret-reader"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
45
src/main.rs
45
src/main.rs
@@ -1,16 +1,16 @@
|
||||
use anyhow::Result;
|
||||
use askama::Template;
|
||||
use axum::{
|
||||
extract::State,
|
||||
extract::{Query, State},
|
||||
http::StatusCode,
|
||||
response::{Html, IntoResponse},
|
||||
response::{Html, IntoResponse, Response},
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use clap::Parser;
|
||||
use k8s_openapi::api::core::v1::Secret;
|
||||
use kube::{Api, Client};
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use tracing::{error, info};
|
||||
use tracing_subscriber;
|
||||
@@ -48,6 +48,12 @@ struct IndexTemplate {
|
||||
error: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct SecretQuery {
|
||||
name: String,
|
||||
field: String,
|
||||
}
|
||||
|
||||
async fn read_secrets(state: &AppState) -> Result<Vec<SecretData>> {
|
||||
let secrets_api: Api<Secret> = Api::namespaced(state.client.clone(), &state.namespace);
|
||||
let mut result = Vec::new();
|
||||
@@ -125,6 +131,38 @@ async fn health_handler() -> impl IntoResponse {
|
||||
"OK"
|
||||
}
|
||||
|
||||
async fn secret_handler(
|
||||
Query(params): Query<SecretQuery>,
|
||||
State(state): State<Arc<AppState>>,
|
||||
) -> Response {
|
||||
info!("Fetching secret: {} field: {}", params.name, params.field);
|
||||
|
||||
let secrets_api: Api<Secret> = Api::namespaced(state.client.clone(), &state.namespace);
|
||||
|
||||
match secrets_api.get(¶ms.name).await {
|
||||
Ok(secret) => {
|
||||
if let Some(data) = secret.data {
|
||||
if let Some(value) = data.get(¶ms.field) {
|
||||
let decoded = String::from_utf8_lossy(&value.0).to_string();
|
||||
return decoded.into_response();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(string_data) = secret.string_data {
|
||||
if let Some(value) = string_data.get(¶ms.field) {
|
||||
return value.clone().into_response();
|
||||
}
|
||||
}
|
||||
|
||||
(StatusCode::NOT_FOUND, format!("Field '{}' not found in secret '{}'", params.field, params.name)).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to read secret {}: {}", params.name, e);
|
||||
(StatusCode::NOT_FOUND, format!("Secret '{}' not found: {}", params.name, e)).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt::init();
|
||||
@@ -151,6 +189,7 @@ async fn main() -> Result<()> {
|
||||
let app = Router::new()
|
||||
.route("/", get(index_handler))
|
||||
.route("/health", get(health_handler))
|
||||
.route("/secret", get(secret_handler))
|
||||
.with_state(state);
|
||||
|
||||
let addr = format!("0.0.0.0:{}", args.port);
|
||||
|
||||
Reference in New Issue
Block a user