feat: seed Sol agent vault policy + gitea creds, bump v1.0.1
Patches gitea admin credentials into secret/sol for Sol's Gitea integration. Adds sol-agent vault policy with read/write access to sol-tokens/* for user impersonation PATs, plus k8s auth role bound to the matrix namespace.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sunbeam-sdk"
|
name = "sunbeam-sdk"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "Sunbeam SDK — reusable library for cluster management"
|
description = "Sunbeam SDK — reusable library for cluster management"
|
||||||
repository = "https://src.sunbeam.pt/studio/cli"
|
repository = "https://src.sunbeam.pt/studio/cli"
|
||||||
|
|||||||
@@ -1103,4 +1103,50 @@ mod tests {
|
|||||||
];
|
];
|
||||||
assert_eq!(PG_USERS, &expected[..]);
|
assert_eq!(PG_USERS, &expected[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sol_gitea_credential_mapping() {
|
||||||
|
let mut gitea = HashMap::new();
|
||||||
|
gitea.insert("admin-username".to_string(), "gitea_admin".to_string());
|
||||||
|
gitea.insert("admin-password".to_string(), "s3cret".to_string());
|
||||||
|
|
||||||
|
let mut sol_gitea = HashMap::new();
|
||||||
|
if let Some(u) = gitea.get("admin-username") {
|
||||||
|
sol_gitea.insert("gitea-admin-username".to_string(), u.clone());
|
||||||
|
}
|
||||||
|
if let Some(p) = gitea.get("admin-password") {
|
||||||
|
sol_gitea.insert("gitea-admin-password".to_string(), p.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(sol_gitea.len(), 2);
|
||||||
|
assert_eq!(sol_gitea["gitea-admin-username"], "gitea_admin");
|
||||||
|
assert_eq!(sol_gitea["gitea-admin-password"], "s3cret");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sol_gitea_credential_mapping_partial() {
|
||||||
|
let gitea: HashMap<String, String> = HashMap::new();
|
||||||
|
let mut sol_gitea = HashMap::new();
|
||||||
|
if let Some(u) = gitea.get("admin-username") {
|
||||||
|
sol_gitea.insert("gitea-admin-username".to_string(), u.clone());
|
||||||
|
}
|
||||||
|
if let Some(p) = gitea.get("admin-password") {
|
||||||
|
sol_gitea.insert("gitea-admin-password".to_string(), p.clone());
|
||||||
|
}
|
||||||
|
assert!(sol_gitea.is_empty(), "No creds should be mapped when gitea map is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sol_agent_policy_hcl() {
|
||||||
|
let sol_policy_hcl = concat!(
|
||||||
|
"path \"secret/data/sol-tokens/*\" { capabilities = [\"create\", \"read\", \"update\", \"delete\"] }\n",
|
||||||
|
"path \"secret/metadata/sol-tokens/*\" { capabilities = [\"read\", \"delete\", \"list\"] }\n",
|
||||||
|
);
|
||||||
|
assert!(sol_policy_hcl.contains("secret/data/sol-tokens/*"));
|
||||||
|
assert!(sol_policy_hcl.contains("secret/metadata/sol-tokens/*"));
|
||||||
|
assert!(sol_policy_hcl.contains("create"));
|
||||||
|
assert!(sol_policy_hcl.contains("delete"));
|
||||||
|
assert!(sol_policy_hcl.contains("list"));
|
||||||
|
assert_eq!(sol_policy_hcl.lines().count(), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -473,6 +473,21 @@ pub async fn seed_openbao() -> Result<Option<SeedResult>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Patch gitea admin credentials into secret/sol for Sol's Gitea integration.
|
||||||
|
// Uses kv_patch to preserve manually-set keys (matrix-access-token etc.).
|
||||||
|
{
|
||||||
|
let mut sol_gitea = HashMap::new();
|
||||||
|
if let Some(u) = gitea.get("admin-username") {
|
||||||
|
sol_gitea.insert("gitea-admin-username".to_string(), u.clone());
|
||||||
|
}
|
||||||
|
if let Some(p) = gitea.get("admin-password") {
|
||||||
|
sol_gitea.insert("gitea-admin-password".to_string(), p.clone());
|
||||||
|
}
|
||||||
|
if !sol_gitea.is_empty() {
|
||||||
|
bao.kv_patch("secret", "sol", &sol_gitea).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Kubernetes auth for VSO ─────────────────────────────────────────
|
// ── Kubernetes auth for VSO ─────────────────────────────────────────
|
||||||
ok("Configuring Kubernetes auth for VSO...");
|
ok("Configuring Kubernetes auth for VSO...");
|
||||||
let _ = bao.auth_enable("kubernetes", "kubernetes").await;
|
let _ = bao.auth_enable("kubernetes", "kubernetes").await;
|
||||||
@@ -503,6 +518,25 @@ pub async fn seed_openbao() -> Result<Option<SeedResult>> {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// Sol agent policy — read/write access to sol-tokens/* for user impersonation PATs
|
||||||
|
ok("Configuring Kubernetes auth for Sol agent...");
|
||||||
|
let sol_policy_hcl = concat!(
|
||||||
|
"path \"secret/data/sol-tokens/*\" { capabilities = [\"create\", \"read\", \"update\", \"delete\"] }\n",
|
||||||
|
"path \"secret/metadata/sol-tokens/*\" { capabilities = [\"read\", \"delete\", \"list\"] }\n",
|
||||||
|
);
|
||||||
|
bao.write_policy("sol-agent", sol_policy_hcl).await?;
|
||||||
|
|
||||||
|
bao.write(
|
||||||
|
"auth/kubernetes/role/sol-agent",
|
||||||
|
&serde_json::json!({
|
||||||
|
"bound_service_account_names": "default",
|
||||||
|
"bound_service_account_namespaces": "matrix",
|
||||||
|
"policies": "sol-agent",
|
||||||
|
"ttl": "1h"
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Build credentials map
|
// Build credentials map
|
||||||
let mut creds = HashMap::new();
|
let mut creds = HashMap::new();
|
||||||
let field_map: &[(&str, &str, &HashMap<String, String>)] = &[
|
let field_map: &[(&str, &str, &HashMap<String, String>)] = &[
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sunbeam"
|
name = "sunbeam"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "Sunbeam local dev stack manager"
|
description = "Sunbeam local dev stack manager"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user