WIP
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,3 +1,4 @@
|
||||
_secrets.yaml filter=git-crypt diff=git-crypt
|
||||
secrets.yaml filter=git-crypt diff=git-crypt
|
||||
*.agekey filter=git-crypt diff=git-crypt
|
||||
*.key filter=git-crypt diff=git-crypt
|
||||
secrets.yaml filter=git-crypt diff=git-crypt
|
||||
|
||||
1
crete/.gitignore
vendored
Normal file
1
crete/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target/
|
||||
355
crete/Cargo.lock
generated
Normal file
355
crete/Cargo.lock
generated
Normal file
@@ -0,0 +1,355 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "crete"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"minijinja",
|
||||
"optional_struct",
|
||||
"regress",
|
||||
"repo_path_lib",
|
||||
"schemars",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "memo-map"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
|
||||
|
||||
[[package]]
|
||||
name = "minijinja"
|
||||
version = "2.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c54f3bcc034dd74496b5ca929fd0b710186672d5ff0b0f255a9ceb259042ece"
|
||||
dependencies = [
|
||||
"memo-map",
|
||||
"self_cell",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "optional_struct"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14199f59efce6ed2c5854f0abc725c32eedfbd02c6ef82c9733c726f3fc6dc91"
|
||||
dependencies = [
|
||||
"optional_struct_macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "optional_struct_macro"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5eba042d9efe5e108e0df9ce2f85c540fc4f94f41c6821cbcf70ed47c1221da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
|
||||
dependencies = [
|
||||
"ref-cast-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast-impl"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regress"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2057b2325e68a893284d1538021ab90279adac1139957ca2a74426c6f118fb48"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "repo_path_lib"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d4f67a73ddc563e6fb8bac035c9c76de29af2e4ad6031dc49bb5a2cd0742fca"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"ref-cast",
|
||||
"schemars_derive",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.34+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
17
crete/Cargo.toml
Normal file
17
crete/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "crete"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
default-run = "crete"
|
||||
|
||||
[dependencies]
|
||||
minijinja = { version = "2.16.0", features = ["loader"] }
|
||||
optional_struct = "0.5.2"
|
||||
regress = "0.10.5"
|
||||
repo_path_lib = "1.2.4"
|
||||
schemars = { version = "1.2.1", features = ["semver1"] }
|
||||
semver = { version = "1.0.27", features = ["serde"] }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
serde_json = "1.0.149"
|
||||
serde_yaml = "0.9.34"
|
||||
walkdir = "2.5.0"
|
||||
23
crete/src/bin/schemas.rs
Normal file
23
crete/src/bin/schemas.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use std::{fs::File, io::Write};
|
||||
|
||||
use crete::{cluster::Cluster, node::OptionalNode};
|
||||
use repo_path_lib::repo_dir;
|
||||
use schemars::{JsonSchema, schema_for};
|
||||
|
||||
fn write<T>(name: &str)
|
||||
where
|
||||
T: JsonSchema,
|
||||
{
|
||||
let mut path = repo_dir().join("schemas").join(name);
|
||||
path.add_extension("json");
|
||||
let mut file = File::create(path).unwrap();
|
||||
|
||||
let schema = serde_json::to_string_pretty(&schema_for!(T)).unwrap();
|
||||
file.write_all(schema.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
// TODO: Create directory if it does not exist
|
||||
fn main() {
|
||||
write::<Cluster>("cluster");
|
||||
write::<OptionalNode>("node");
|
||||
}
|
||||
69
crete/src/cluster.rs
Normal file
69
crete/src/cluster.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
base_dir,
|
||||
node::{Node, OptionalNode},
|
||||
patch::{PatchEnv, Patches},
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Base {
|
||||
#[serde(default)]
|
||||
pub(crate) kernel_args: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub(crate) patches: Patches,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Version {
|
||||
kubernetes: semver::Version,
|
||||
talos: semver::Version,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub enum ClusterEnv {
|
||||
Production,
|
||||
Staging,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Cluster {
|
||||
#[serde(skip_deserializing)]
|
||||
name: String,
|
||||
version: Version,
|
||||
nodes: Vec<String>,
|
||||
cluster_env: ClusterEnv,
|
||||
control_plane_ip: Ipv4Addr,
|
||||
#[serde(default, skip_serializing)]
|
||||
pub(crate) default: OptionalNode,
|
||||
#[serde(skip_serializing)]
|
||||
pub(crate) base: Base,
|
||||
// pub secrets_file: PathBuf,
|
||||
}
|
||||
|
||||
impl Cluster {
|
||||
pub fn get(cluster_name: &str) -> Self {
|
||||
let mut path = base_dir().join("clusters").join(cluster_name);
|
||||
path.add_extension("yaml");
|
||||
let content = std::fs::read_to_string(path).unwrap();
|
||||
|
||||
let mut cluster: Self = serde_yaml::from_str(&content).unwrap();
|
||||
cluster.name = cluster_name.to_string();
|
||||
|
||||
cluster
|
||||
}
|
||||
|
||||
pub fn nodes(&self, env: PatchEnv) -> Vec<Node> {
|
||||
self.nodes
|
||||
.iter()
|
||||
.map(|node_name| Node::get(node_name, &env, self))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
11
crete/src/lib.rs
Normal file
11
crete/src/lib.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
pub mod cluster;
|
||||
pub mod node;
|
||||
pub mod patch;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use repo_path_lib::repo_dir;
|
||||
|
||||
fn base_dir() -> PathBuf {
|
||||
repo_dir().join("talos")
|
||||
}
|
||||
10
crete/src/main.rs
Normal file
10
crete/src/main.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use crete::{cluster::Cluster, patch::PatchEnv};
|
||||
|
||||
fn main() {
|
||||
let cluster = Cluster::get("testing");
|
||||
|
||||
let patches = PatchEnv::default();
|
||||
let nodes = cluster.nodes(patches);
|
||||
|
||||
println!("{:#?}", nodes);
|
||||
}
|
||||
174
crete/src/node.rs
Normal file
174
crete/src/node.rs
Normal file
@@ -0,0 +1,174 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use optional_struct::{Applicable, optional_struct};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
|
||||
use crate::{
|
||||
base_dir,
|
||||
cluster::Cluster,
|
||||
patch::{OptionalPatches, PatchEnv, Patches},
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, Copy, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum NodeType {
|
||||
Worker,
|
||||
ControlPlane,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, Copy, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum NodeArch {
|
||||
Amd64,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct FileSecret {
|
||||
file: String,
|
||||
}
|
||||
|
||||
fn deserialize_secret_file<'de, D>(deserializer: D) -> Result<String, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let secret: FileSecret = Deserialize::deserialize(deserializer)?;
|
||||
let path = base_dir().join("secrets").join(secret.file);
|
||||
let content = std::fs::read_to_string(path).unwrap().trim().to_owned();
|
||||
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
fn file_secret_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
|
||||
generator.subschema_for::<FileSecret>()
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
enum Secret {
|
||||
String(String),
|
||||
#[serde(deserialize_with = "deserialize_secret_file")]
|
||||
#[schemars(schema_with = "file_secret_schema")]
|
||||
File(String),
|
||||
}
|
||||
|
||||
impl From<Secret> for String {
|
||||
fn from(value: Secret) -> Self {
|
||||
match value {
|
||||
Secret::String(value) | Secret::File(value) => value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[optional_struct]
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct Tailscale {
|
||||
auth_key: Secret,
|
||||
advertise_routes: bool,
|
||||
#[serde(default)]
|
||||
server: Option<String>,
|
||||
}
|
||||
|
||||
#[optional_struct]
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct Network {
|
||||
interface: String,
|
||||
ip: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
dns: [Ipv4Addr; 2],
|
||||
#[optional_rename(OptionalTailscale)]
|
||||
#[optional_wrap]
|
||||
tailscale: Tailscale,
|
||||
}
|
||||
|
||||
#[optional_struct]
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct Install {
|
||||
auto: bool,
|
||||
disk: String,
|
||||
serial: Option<String>,
|
||||
}
|
||||
|
||||
#[optional_struct]
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Node {
|
||||
#[serde(skip_deserializing)]
|
||||
hostname: String,
|
||||
arch: NodeArch,
|
||||
r#type: NodeType,
|
||||
#[optional_rename(OptionalNetwork)]
|
||||
#[optional_wrap]
|
||||
network: Network,
|
||||
ntp: String,
|
||||
#[optional_rename(OptionalInstall)]
|
||||
#[optional_wrap]
|
||||
install: Install,
|
||||
kernel_args: Vec<String>,
|
||||
#[optional_rename(OptionalPatches)]
|
||||
#[optional_wrap]
|
||||
pub(crate) patches: Patches,
|
||||
// TODO: Per machine patches, append to global list of patches
|
||||
// Any patches are specified under default they will get overridden
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn get(node_name: &str, env: &PatchEnv, cluster: &Cluster) -> Self {
|
||||
let mut path = base_dir().join("nodes").join(node_name);
|
||||
let named = OptionalNode {
|
||||
hostname: Some(
|
||||
path.file_name()
|
||||
.expect("Path should be valid")
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
),
|
||||
..OptionalNode::default()
|
||||
};
|
||||
|
||||
path.add_extension("yaml");
|
||||
let content = std::fs::read_to_string(path).unwrap();
|
||||
|
||||
let node: OptionalNode = serde_yaml::from_str(&content).unwrap();
|
||||
|
||||
// We want all vectors to be empty vectors by default
|
||||
// Sadly we have to this manually
|
||||
// TODO: Find a better way of doing this
|
||||
let default = OptionalNode {
|
||||
patches: Some(OptionalPatches {
|
||||
all: Some(vec![]),
|
||||
control_plane: Some(vec![]),
|
||||
}),
|
||||
kernel_args: vec![].into(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Combine all the optional node parts into complete struct
|
||||
let mut node: Node = default
|
||||
// Apply cluster default settings
|
||||
.apply(cluster.default.clone())
|
||||
// Apply hostname based on filename
|
||||
.apply(named)
|
||||
// Override node specific settings
|
||||
.apply(node)
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
// Prepend the cluster base values
|
||||
let mut kernel_args = cluster.base.kernel_args.clone();
|
||||
kernel_args.extend(node.kernel_args);
|
||||
node.kernel_args = kernel_args;
|
||||
|
||||
let patches = cluster.base.patches.clone().extend(node.patches);
|
||||
node.patches = patches;
|
||||
|
||||
// Render patches
|
||||
node.patches = node.patches.clone().render(env, cluster, &node);
|
||||
|
||||
node
|
||||
}
|
||||
}
|
||||
117
crete/src/patch.rs
Normal file
117
crete/src/patch.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use std::{
|
||||
fmt::{Display, Formatter},
|
||||
net::Ipv4Addr,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use minijinja::{Environment, context};
|
||||
use optional_struct::optional_struct;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::{base_dir, cluster::Cluster, node::Node};
|
||||
|
||||
pub struct PatchEnv<'e>(Environment<'e>);
|
||||
|
||||
impl<'e> Default for PatchEnv<'e> {
|
||||
fn default() -> Self {
|
||||
let mut env = Environment::new();
|
||||
env.set_undefined_behavior(minijinja::UndefinedBehavior::Strict);
|
||||
|
||||
let dir = base_dir().join("patches");
|
||||
for entry in WalkDir::new(&dir)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.metadata().unwrap().is_file())
|
||||
{
|
||||
let source = std::fs::read_to_string(entry.path()).unwrap();
|
||||
let name = entry
|
||||
.path()
|
||||
.strip_prefix(&dir)
|
||||
.unwrap()
|
||||
.with_extension("")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
env.add_filter("to_prefix", |netmask: String| {
|
||||
let netmask = Ipv4Addr::from_str(&netmask).map_err(|err| {
|
||||
minijinja::Error::new(minijinja::ErrorKind::InvalidOperation, err.to_string())
|
||||
})?;
|
||||
let mask = netmask.to_bits();
|
||||
let prefix = mask.leading_ones();
|
||||
|
||||
if mask.checked_shl(prefix).unwrap_or(0) == 0 {
|
||||
Ok(prefix as u8)
|
||||
} else {
|
||||
Err(minijinja::Error::new(
|
||||
minijinja::ErrorKind::InvalidOperation,
|
||||
"invalid IP prefix length",
|
||||
))
|
||||
}
|
||||
});
|
||||
|
||||
env.add_template_owned(name, source).unwrap();
|
||||
}
|
||||
|
||||
Self(env)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum Patch {
|
||||
Name(String),
|
||||
#[serde(skip)]
|
||||
Resolved(serde_yaml::Value),
|
||||
}
|
||||
|
||||
#[optional_struct]
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, PartialEq, Eq, Default)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Patches {
|
||||
pub(crate) all: Vec<Patch>,
|
||||
pub(crate) control_plane: Vec<Patch>,
|
||||
}
|
||||
|
||||
fn render(patches: Vec<Patch>, env: &PatchEnv, cluster: &Cluster, node: &Node) -> Vec<Patch> {
|
||||
patches
|
||||
.into_iter()
|
||||
.map(|patch| {
|
||||
if let Patch::Name(name) = patch {
|
||||
Patch::Resolved(
|
||||
serde_yaml::from_str(
|
||||
&env.0
|
||||
.get_template(&name)
|
||||
.unwrap()
|
||||
.render(context!(node, cluster))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
patch
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl Patches {
|
||||
pub(crate) fn extend(mut self, other: Self) -> Self {
|
||||
self.all.extend(other.all);
|
||||
self.control_plane.extend(other.control_plane);
|
||||
|
||||
Self {
|
||||
all: self.all,
|
||||
control_plane: self.control_plane,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn render(self, env: &PatchEnv, cluster: &Cluster, node: &Node) -> Self {
|
||||
Self {
|
||||
all: render(self.all.clone(), env, cluster, node),
|
||||
control_plane: render(self.control_plane.clone(), env, cluster, node),
|
||||
}
|
||||
}
|
||||
}
|
||||
354
schemas/cluster.json
Normal file
354
schemas/cluster.json
Normal file
@@ -0,0 +1,354 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Cluster",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"base": {
|
||||
"$ref": "#/$defs/Base",
|
||||
"writeOnly": true
|
||||
},
|
||||
"clusterEnv": {
|
||||
"$ref": "#/$defs/ClusterEnv"
|
||||
},
|
||||
"controlPlaneIp": {
|
||||
"type": "string",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/$defs/OptionalNode",
|
||||
"writeOnly": true
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"$ref": "#/$defs/Version"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"version",
|
||||
"nodes",
|
||||
"clusterEnv",
|
||||
"controlPlaneIp",
|
||||
"base"
|
||||
],
|
||||
"$defs": {
|
||||
"Base": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kernelArgs": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"patches": {
|
||||
"$ref": "#/$defs/Patches",
|
||||
"default": {
|
||||
"all": [],
|
||||
"controlPlane": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ClusterEnv": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"production",
|
||||
"staging"
|
||||
]
|
||||
},
|
||||
"FileSecret": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file"
|
||||
]
|
||||
},
|
||||
"NodeArch": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"amd64"
|
||||
]
|
||||
},
|
||||
"NodeType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"worker",
|
||||
"controlPlane"
|
||||
]
|
||||
},
|
||||
"OptionalInstall": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auto": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"disk": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"serial": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalNetwork": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dns": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
},
|
||||
"gateway": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "ipv4"
|
||||
},
|
||||
"interface": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"ip": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "ipv4"
|
||||
},
|
||||
"netmask": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "ipv4"
|
||||
},
|
||||
"tailscale": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalTailscale"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalNode": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"arch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/NodeArch"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"install": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalInstall"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"kernelArgs": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"network": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalNetwork"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ntp": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"patches": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalPatches"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/NodeType"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalPatches": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/$defs/Patch"
|
||||
}
|
||||
},
|
||||
"controlPlane": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/$defs/Patch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalTailscale": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"advertiseRoutes": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"authKey": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Secret"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"server": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Patch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Patches": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/Patch"
|
||||
}
|
||||
},
|
||||
"controlPlane": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/Patch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"all",
|
||||
"controlPlane"
|
||||
]
|
||||
},
|
||||
"Secret": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/FileSecret"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SemVer": {
|
||||
"type": "string",
|
||||
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
|
||||
},
|
||||
"Version": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kubernetes": {
|
||||
"$ref": "#/$defs/SemVer"
|
||||
},
|
||||
"talos": {
|
||||
"$ref": "#/$defs/SemVer"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"kubernetes",
|
||||
"talos"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
248
schemas/node.json
Normal file
248
schemas/node.json
Normal file
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "OptionalNode",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"arch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/NodeArch"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"install": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalInstall"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"kernelArgs": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"network": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalNetwork"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ntp": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"patches": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalPatches"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/NodeType"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"FileSecret": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file"
|
||||
]
|
||||
},
|
||||
"NodeArch": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"amd64"
|
||||
]
|
||||
},
|
||||
"NodeType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"worker",
|
||||
"controlPlane"
|
||||
]
|
||||
},
|
||||
"OptionalInstall": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auto": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"disk": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"serial": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalNetwork": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dns": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "ipv4"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
},
|
||||
"gateway": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "ipv4"
|
||||
},
|
||||
"interface": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"ip": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "ipv4"
|
||||
},
|
||||
"netmask": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "ipv4"
|
||||
},
|
||||
"tailscale": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/OptionalTailscale"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalPatches": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/$defs/Patch"
|
||||
}
|
||||
},
|
||||
"controlPlane": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/$defs/Patch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OptionalTailscale": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"advertiseRoutes": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"authKey": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Secret"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"server": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Patch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Secret": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/FileSecret"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
63
talos/clusters/testing.yaml
Normal file
63
talos/clusters/testing.yaml
Normal file
@@ -0,0 +1,63 @@
|
||||
# yaml-language-server: $schema=../../schemas/cluster.json
|
||||
version:
|
||||
kubernetes: 1.34.1
|
||||
talos: 1.11.3
|
||||
clusterEnv: staging
|
||||
controlPlaneIp: 192.168.1.100
|
||||
nodes:
|
||||
- testing/talos-vm
|
||||
# secrets:
|
||||
# age: !file testing/age.key
|
||||
# talos: testing/secrets.yaml
|
||||
|
||||
base:
|
||||
kernelArgs:
|
||||
- talos.platform=metal
|
||||
- console=tty0
|
||||
- init_on_alloc=1
|
||||
- init_on_free=1
|
||||
- slab_nomerge
|
||||
- pti=on
|
||||
- consoleblank=0
|
||||
- nvme_core.io_timeout=4294967295
|
||||
- printk.devkmsg=on
|
||||
- selinux=1
|
||||
- lockdown=confidentiality
|
||||
patches:
|
||||
all:
|
||||
- system/hostname
|
||||
- system/install-disk
|
||||
- system/network
|
||||
- networking/vip
|
||||
- networking/tailscale
|
||||
- networking/cilium
|
||||
- spegel
|
||||
- storage/longhorn
|
||||
- storage/longhorn/user-volume
|
||||
- storage/local-path-provisioner/user-volume
|
||||
- storage/limit-ephemeral
|
||||
- metrics/all
|
||||
controlPlane:
|
||||
- system/allow-control-plane-workloads
|
||||
# - sops
|
||||
- flux/cluster-variables
|
||||
- metrics/control-plane
|
||||
- networking/gateway-api
|
||||
default:
|
||||
arch: amd64
|
||||
network:
|
||||
interface: enp1s0
|
||||
netmask: 255.255.252.0
|
||||
gateway: 192.168.1.1
|
||||
dns:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
tailscale:
|
||||
server: https://headscale.huizinga.dev
|
||||
authKey:
|
||||
file: tailscale.key
|
||||
advertiseRoutes: true
|
||||
ntp: nl.pool.ntp.org
|
||||
install:
|
||||
auto: true
|
||||
disk: /dev/vda
|
||||
4
talos/nodes/testing/talos-vm.yaml
Normal file
4
talos/nodes/testing/talos-vm.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
# yaml-language-server: $schema=../../../schemas/node.json
|
||||
type: controlPlane
|
||||
network:
|
||||
ip: 192.168.1.2
|
||||
18
talos/patches/flux/cluster-variables.yaml
Normal file
18
talos/patches/flux/cluster-variables.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
cluster:
|
||||
inlineManifests:
|
||||
- name: cluster-variables
|
||||
contents: |
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: flux-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cluster-variables
|
||||
namespace: flux-system
|
||||
data:
|
||||
cluster_env: {{ cluster.clusterEnv }}
|
||||
5
talos/patches/metrics/all.yaml
Normal file
5
talos/patches/metrics/all.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
kubelet:
|
||||
extraArgs:
|
||||
rotate-server-certificates: "true"
|
||||
5
talos/patches/metrics/control-plane.yaml
Normal file
5
talos/patches/metrics/control-plane.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
cluster:
|
||||
extraManifests:
|
||||
- https://raw.githubusercontent.com/alex1989hu/kubelet-serving-cert-approver/main/deploy/standalone-install.yaml
|
||||
- https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
|
||||
12
talos/patches/networking/cilium.yaml
Normal file
12
talos/patches/networking/cilium.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
features:
|
||||
hostDNS:
|
||||
# This option is enabled by default and causes issues with cilium
|
||||
forwardKubeDNSToHost: false
|
||||
cluster:
|
||||
network:
|
||||
cni:
|
||||
name: none
|
||||
proxy:
|
||||
disabled: true
|
||||
4
talos/patches/networking/gateway-api.yaml
Normal file
4
talos/patches/networking/gateway-api.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
cluster:
|
||||
extraManifests:
|
||||
- https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml
|
||||
8
talos/patches/networking/tailscale.yaml
Normal file
8
talos/patches/networking/tailscale.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
apiVersion: v1alpha1
|
||||
kind: ExtensionServiceConfig
|
||||
name: tailscale
|
||||
environment:
|
||||
- TS_AUTHKEY={{ node.network.tailscale.authKey }}
|
||||
- TS_EXTRA_ARGS={% if node.network.tailscale.server %}--login-server {{ node.network.tailscale.server }} {% endif %}--advertise-tags=tag:cluster-{{ cluster.name }}
|
||||
- TS_ROUTES={% if node.network.tailscale.advertiseRoutes -%} {{node.network.ip}}/{{ node.network.netmask | to_prefix }} {%- endif %}
|
||||
7
talos/patches/networking/vip.yaml
Normal file
7
talos/patches/networking/vip.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
network:
|
||||
interfaces:
|
||||
- interface: "{{node.network.interface}}"
|
||||
vip:
|
||||
ip: "{{cluster.controlPlaneIp}}"
|
||||
18
talos/patches/sops.yaml
Normal file
18
talos/patches/sops.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
cluster:
|
||||
inlineManifests:
|
||||
- name: sops-key
|
||||
contents: |
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: flux-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: sops-gpg
|
||||
namespace: flux-system
|
||||
data:
|
||||
age.agekey: |
|
||||
{{ helper.load_secret(node.cluster.sopsKeyFile) }}
|
||||
8
talos/patches/spegel.yaml
Normal file
8
talos/patches/spegel.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
files:
|
||||
- path: /etc/cri/conf.d/20-customization.part
|
||||
op: create
|
||||
content: |
|
||||
[plugins."io.containerd.cri.v1.images"]
|
||||
discard_unpacked_layers = false
|
||||
6
talos/patches/storage/limit-ephemeral.yaml
Normal file
6
talos/patches/storage/limit-ephemeral.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
apiVersion: v1alpha1
|
||||
kind: VolumeConfig
|
||||
name: EPHEMERAL
|
||||
provisioning:
|
||||
maxSize: 30GB
|
||||
@@ -0,0 +1,9 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
apiVersion: v1alpha1
|
||||
kind: UserVolumeConfig
|
||||
name: local-path-provisioner
|
||||
provisioning:
|
||||
diskSelector:
|
||||
match: system_disk
|
||||
grow: true
|
||||
maxSize: 10GB
|
||||
11
talos/patches/storage/longhorn.yaml
Normal file
11
talos/patches/storage/longhorn.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
kubelet:
|
||||
extraMounts:
|
||||
- destination: /var/lib/longhorn
|
||||
type: bind
|
||||
source: /var/lib/longhorn
|
||||
options:
|
||||
- bind
|
||||
- rshared
|
||||
- rw
|
||||
9
talos/patches/storage/longhorn/user-volume.yaml
Normal file
9
talos/patches/storage/longhorn/user-volume.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
apiVersion: v1alpha1
|
||||
kind: UserVolumeConfig
|
||||
name: longhorn
|
||||
provisioning:
|
||||
diskSelector:
|
||||
match: system_disk
|
||||
grow: true
|
||||
maxSize: 2000GB
|
||||
17
talos/patches/storage/openebs.yaml
Normal file
17
talos/patches/storage/openebs.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
# This is only needed on nodes that will have storage
|
||||
sysctls:
|
||||
vm.nr_hugepages: "1024"
|
||||
nodeLabels:
|
||||
openebs.io/engine: mayastor
|
||||
# This is needed on ALL nodes
|
||||
kubelet:
|
||||
extraMounts:
|
||||
- destination: /var/local
|
||||
type: bind
|
||||
source: /var/local
|
||||
options:
|
||||
- bind
|
||||
- rshared
|
||||
- rw
|
||||
3
talos/patches/system/allow-control-plane-workloads.yaml
Normal file
3
talos/patches/system/allow-control-plane-workloads.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
cluster:
|
||||
allowSchedulingOnControlPlanes: true
|
||||
4
talos/patches/system/hostname.yaml
Normal file
4
talos/patches/system/hostname.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
network:
|
||||
hostname: "{{node.hostname}}"
|
||||
4
talos/patches/system/install-disk.yaml
Normal file
4
talos/patches/system/install-disk.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
install:
|
||||
disk: "{{node.install.disk}}"
|
||||
11
talos/patches/system/network.yaml
Normal file
11
talos/patches/system/network.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/siderolabs/talos/refs/heads/release-1.11/website/content/v1.11/schemas/config.schema.json
|
||||
machine:
|
||||
network:
|
||||
interfaces:
|
||||
- interface: "{{node.network.interface}}"
|
||||
dhcp: false
|
||||
addresses:
|
||||
- "{{node.network.ip}}"
|
||||
routes:
|
||||
- network: 0.0.0.0/0
|
||||
gateway: "{{node.network.gateway}}"
|
||||
BIN
talos/secrets/tailscale.key
Normal file
BIN
talos/secrets/tailscale.key
Normal file
Binary file not shown.
BIN
talos/secrets/testing/age.key
Normal file
BIN
talos/secrets/testing/age.key
Normal file
Binary file not shown.
BIN
talos/secrets/testing/secrets.yaml
Normal file
BIN
talos/secrets/testing/secrets.yaml
Normal file
Binary file not shown.
Reference in New Issue
Block a user