WIP
This commit is contained in:
139
crete/src/node.rs
Normal file
139
crete/src/node.rs
Normal file
@@ -0,0 +1,139 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use optional_struct::{Applicable, optional_struct};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
base_dir,
|
||||
cluster::Cluster,
|
||||
patch::{OptionalPatches, PatchEnv, Patches},
|
||||
schematic::Schematic,
|
||||
secret::Secret,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, Copy, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum NodeType {
|
||||
Worker,
|
||||
#[serde(rename(serialize = "controlplane"))]
|
||||
ControlPlane,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, Copy, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum NodeArch {
|
||||
Amd64,
|
||||
}
|
||||
|
||||
#[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,
|
||||
schematic: Schematic,
|
||||
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,
|
||||
sops: Secret,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user