1use std::process::Command;
2
3use rootcause::prelude::ResultExt as _;
4use rootcause::report;
5use serde::Deserialize;
6
7#[derive(Debug, Deserialize)]
9#[expect(dead_code, reason = "Unused fields are kept for completeness")]
10pub struct VaultReadOutput {
11 pub data: VaultCreds,
13 lease_duration: i32,
15 lease_id: String,
17 renewable: bool,
19 request_id: String,
21 warnings: Vec<String>,
23}
24
25#[derive(Debug, Deserialize)]
27pub struct VaultCreds {
28 pub password: String,
30 pub username: String,
32}
33
34pub fn log_into_vault_if_required() -> rootcause::Result<()> {
42 let token_lookup = Command::new("vault").args(["token", "lookup"]).output()?;
43 if token_lookup.status.success() {
44 return Ok(());
45 }
46 let stderr = std::str::from_utf8(&token_lookup.stderr)
47 .context("error invalid utf-8 stderr")
48 .attach_with(|| format!("cmd=\"vault token lookup\" stderr={:?}", token_lookup.stderr))?
49 .trim();
50 if !stderr.contains("permission denied") {
51 Err(report!("error checking vault token")).attach_with(|| format!("stderr={stderr:?}"))?;
52 }
53
54 let login = Command::new("vault")
55 .args(["login", "-method=oidc", "-path=okta", "--no-print"])
56 .output()?;
57 if !login.status.success() {
58 let stderr = std::str::from_utf8(&login.stderr)
59 .context("error invalid utf-8 stderr")
60 .attach_with(|| format!("cmd=\"vault login\" stderr={:?}", login.stderr))?
61 .trim();
62 Err(report!("error logging into vault")).attach_with(|| format!("stderr={stderr:?}"))?;
63 }
64
65 Ok(())
66}