mirror of
https://github.com/house-of-vanity/k8s-secrets.git
synced 2026-02-04 09:47:58 +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",
|
"humansize",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "secret-reader"
|
name = "secret-reader"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
45
src/main.rs
45
src/main.rs
@@ -1,16 +1,16 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::{Query, State},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse, Response},
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use k8s_openapi::api::core::v1::Secret;
|
use k8s_openapi::api::core::v1::Secret;
|
||||||
use kube::{Api, Client};
|
use kube::{Api, Client};
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
use tracing_subscriber;
|
use tracing_subscriber;
|
||||||
@@ -48,6 +48,12 @@ struct IndexTemplate {
|
|||||||
error: Option<String>,
|
error: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct SecretQuery {
|
||||||
|
name: String,
|
||||||
|
field: String,
|
||||||
|
}
|
||||||
|
|
||||||
async fn read_secrets(state: &AppState) -> Result<Vec<SecretData>> {
|
async fn read_secrets(state: &AppState) -> Result<Vec<SecretData>> {
|
||||||
let secrets_api: Api<Secret> = Api::namespaced(state.client.clone(), &state.namespace);
|
let secrets_api: Api<Secret> = Api::namespaced(state.client.clone(), &state.namespace);
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
@@ -125,6 +131,38 @@ async fn health_handler() -> impl IntoResponse {
|
|||||||
"OK"
|
"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]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
@@ -151,6 +189,7 @@ async fn main() -> Result<()> {
|
|||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(index_handler))
|
.route("/", get(index_handler))
|
||||||
.route("/health", get(health_handler))
|
.route("/health", get(health_handler))
|
||||||
|
.route("/secret", get(secret_handler))
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
let addr = format!("0.0.0.0:{}", args.port);
|
let addr = format!("0.0.0.0:{}", args.port);
|
||||||
|
|||||||
Reference in New Issue
Block a user