Compare commits

..

6 Commits

6 changed files with 376 additions and 186 deletions

541
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@ codegen-units = 1
[dependencies] [dependencies]
async-compression = { version = "0.4.27", features = ["tokio", "zstd"] } async-compression = { version = "0.4.27", features = ["tokio", "zstd"] }
base32 = "0.5.1" base32 = "0.5.1"
base64 = "0.22.1"
bytes = "1.10.1" bytes = "1.10.1"
chrono = { version = "0.4.41", default-features = false, features = ["clock", "now"] } chrono = { version = "0.4.41", default-features = false, features = ["clock", "now"] }
clap = { version = "4.5.40", features = ["derive", "env"] } clap = { version = "4.5.40", features = ["derive", "env"] }

View File

@ -3,6 +3,8 @@ use log::info;
use std::path::Path; use std::path::Path;
use tokio::fs; use tokio::fs;
use crate::base64_decode;
pub async fn files(files: &[crate::File], root: &str) -> Result<()> { pub async fn files(files: &[crate::File], root: &str) -> Result<()> {
for file in files { for file in files {
let path = chroot(root, &file.path); let path = chroot(root, &file.path);
@ -15,6 +17,10 @@ pub async fn files(files: &[crate::File], root: &str) -> Result<()> {
use crate::FileKind as K; use crate::FileKind as K;
match &file.kind { match &file.kind {
K::Content(content) => fs::write(path, content.as_bytes()).await?, K::Content(content) => fs::write(path, content.as_bytes()).await?,
K::Content64(content) => {
let content = base64_decode(content)?;
fs::write(path, content).await?
}
K::Dir(true) => fs::create_dir(path).await?, K::Dir(true) => fs::create_dir(path).await?,
K::Dir(false) => {} // shouldn't happen, but semantic is to ignore K::Dir(false) => {} // shouldn't happen, but semantic is to ignore
K::Symlink(tgt) => fs::symlink(tgt, path).await?, K::Symlink(tgt) => fs::symlink(tgt, path).await?,

View File

@ -105,7 +105,7 @@ impl Default for SSHServer {
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct LvmVG { pub struct LvmVG {
#[serde(alias = "vg")] #[serde(rename = "vg", alias = "name")]
pub name: String, pub name: String,
pub pvs: LvmPV, pub pvs: LvmPV,

View File

@ -170,6 +170,8 @@ pub struct Config {
pub host_templates: Vec<HostConfig>, pub host_templates: Vec<HostConfig>,
#[serde(default, rename = "SSLConfig")] #[serde(default, rename = "SSLConfig")]
pub ssl_config: String, pub ssl_config: String,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub extra_ca_certs: Map<String, String>,
} }
// compensate for go's encoder pitfalls // compensate for go's encoder pitfalls

View File

@ -1,10 +1,10 @@
pub mod apply; pub mod apply;
pub mod proxy;
pub mod bootstrap; pub mod bootstrap;
pub mod dls; pub mod dls;
pub mod dynlay; pub mod dynlay;
pub mod fs; pub mod fs;
pub mod logger; pub mod logger;
pub mod proxy;
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)] #[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
pub struct Config { pub struct Config {
@ -63,9 +63,10 @@ pub struct File {
} }
#[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)] #[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "lowercase")]
pub enum FileKind { pub enum FileKind {
Content(String), Content(String),
Content64(String),
Symlink(String), Symlink(String),
Dir(bool), Dir(bool),
} }
@ -80,3 +81,8 @@ impl Config {
self.files.iter().find(|f| f.path == path) self.files.iter().find(|f| f.path == path)
} }
} }
pub fn base64_decode(s: &str) -> Result<Vec<u8>, base64::DecodeError> {
use base64::{prelude::BASE64_STANDARD_NO_PAD as B64, Engine};
B64.decode(s.trim_end_matches('='))
}