photoncloud-monorepo/nix/modules/nix-nos/topology.nix

78 lines
2.1 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.nix-nos;
clusterConfigLib = import ../cluster-config-lib.nix { inherit lib; };
nodeType = clusterConfigLib.mkNodeType types;
# Cluster definition type
clusterType = types.submodule {
options = {
name = mkOption {
type = types.str;
default = "plasmacloud-cluster";
description = "Cluster name";
};
nodes = mkOption {
type = types.attrsOf nodeType;
default = {};
description = "Map of node names to their configurations";
example = literalExpression ''
{
"node01" = {
role = "control-plane";
ip = "10.0.1.10";
services = [ "chainfire" "flaredb" ];
};
}
'';
};
bootstrapNode = mkOption {
type = types.nullOr types.str;
default = null;
description = "Name of the bootstrap node (first control-plane node if null)";
};
};
};
in {
options.nix-nos = {
enable = mkEnableOption "Nix-NOS declarative cluster management";
clusters = mkOption {
type = types.attrsOf clusterType;
default = {};
description = "Map of cluster names to their configurations";
};
# Helper function to generate cluster-config.json for a specific node
generateClusterConfig = mkOption {
type = types.functionTo types.attrs;
default = { hostname, clusterName ? "plasmacloud" }:
let
cluster = cfg.clusters.${clusterName} or (throw "Cluster ${clusterName} not found");
in clusterConfigLib.mkClusterConfig {
inherit cluster hostname;
bootstrapNodeName =
if cluster.bootstrapNode != null
then cluster.bootstrapNode
else null;
};
description = "Function to generate cluster-config.json for a specific hostname";
};
};
config = mkIf cfg.enable {
# Ensure at least one cluster is defined
assertions = [
{
assertion = (builtins.length (attrNames cfg.clusters)) > 0;
message = "nix-nos.clusters must contain at least one cluster definition";
}
];
};
}