xianyun_infra/
traefik_tlsstore.rs1use xianyun_backends::kustomize::FileSystem;
17
18pub const FILES: &[(&str, &str)] = &[
20 (
21 "kustomization.yaml",
22 include_str!("traefik_tlsstore_assets/kustomization.yaml"),
23 ),
24 (
25 "tlsstore.yaml",
26 include_str!("traefik_tlsstore_assets/tlsstore.yaml"),
27 ),
28];
29
30pub fn write_files(fsys: &dyn FileSystem, dir: &str) -> std::io::Result<()> {
33 for (name, content) in FILES {
34 fsys.write_file(&format!("{dir}/{name}"), content.as_bytes())?;
35 }
36
37 Ok(())
38}
39
40#[cfg(test)]
41mod tests {
42 use std::collections::HashMap;
43 use std::sync::Mutex;
44
45 use xianyun_backends::kustomize::{Backend, Client, FileSystem};
46 use xianyun_executor::exec::Client as ExecClient;
47
48 use super::*;
49
50 #[derive(Default)]
53 struct InMemoryFs {
54 files: Mutex<HashMap<String, Vec<u8>>>,
55 }
56
57 impl FileSystem for InMemoryFs {
58 fn write_file(&self, path: &str, content: &[u8]) -> std::io::Result<()> {
59 self.files
60 .lock()
61 .unwrap()
62 .insert(path.to_string(), content.to_vec());
63 Ok(())
64 }
65
66 fn read_file(&self, path: &str) -> std::io::Result<Vec<u8>> {
67 self.files
68 .lock()
69 .unwrap()
70 .get(path)
71 .cloned()
72 .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, path.to_string()))
73 }
74
75 fn walk(&self, dir: &str) -> std::io::Result<Vec<String>> {
76 let prefix = if dir.ends_with('/') {
77 dir.to_string()
78 } else {
79 format!("{dir}/")
80 };
81 Ok(self
82 .files
83 .lock()
84 .unwrap()
85 .keys()
86 .filter(|path| path.starts_with(&prefix) || *path == dir)
87 .cloned()
88 .collect())
89 }
90 }
91
92 #[test]
103 fn tls_store_overlay_renders() {
104 let fsys = InMemoryFs::default();
105 write_files(&fsys, "/overlay").unwrap();
106
107 let backend = Client::with_fs(std::sync::Arc::new(fsys), std::sync::Arc::new(ExecClient));
108
109 let rendered = backend.build("/overlay").unwrap();
110
111 let doc: serde_yaml::Value =
112 serde_yaml::from_slice(&rendered).expect("the overlay must render a single resource");
113
114 assert_eq!(
115 doc["apiVersion"],
116 serde_yaml::Value::from("traefik.io/v1alpha1")
117 );
118 assert_eq!(doc["kind"], serde_yaml::Value::from("TLSStore"));
119
120 let meta = doc.get("metadata").expect("metadata must be present");
121 assert_eq!(meta["name"], serde_yaml::Value::from("default"));
124 assert_eq!(meta["namespace"], serde_yaml::Value::from("kube-system"));
125
126 let spec = doc.get("spec").expect("spec must be present");
127 let default_cert = spec
128 .get("defaultCertificate")
129 .expect("spec.defaultCertificate must be present");
130 assert_eq!(
131 default_cert["secretName"],
132 serde_yaml::Value::from("xianyun-wildcard-tls"),
133 "the default certificate must name the Secret the dev-CA wildcard Certificate issues"
134 );
135 }
136}