{ lib, flake-parts-lib, ... }: { options = { perSystem = flake-parts-lib.mkPerSystemOption ( { config, pkgs, ... }: { options = { kubeClusters = lib.mkOption { default = {}; description = "Attribute set of Kubernetes/Talos clusters."; type = lib.types.attrsOf ( lib.types.submodule ( {config, ...}: { config = { toolchainPkgs = lib.pipe config.toolchain [ builtins.attrValues (builtins.filter (p: p != null)) ]; }; options = { toolchainPkgs = lib.mkOption { type = lib.types.listOf lib.types.package; description = "Calculated toolchain packages for this cluster"; readOnly = true; }; objects = lib.mkOption { default = []; description = "List of cluster objects."; type = lib.types.listOf ( lib.types.submodule { options = { type = lib.mkOption { description = "Object type."; type = lib.types.enum [ "kubeObject" "talosObject" "helmObject" "helmfileObject" ]; }; content = lib.mkOption { description = "Raw content, validated by kubeconform/talosctl."; type = lib.types.anything; }; }; } ); }; toolchain = lib.mkOption { default = {}; type = lib.types.submodule { options = { kubePkg = lib.mkOption { description = "Place for kubectl."; type = lib.types.package; default = pkgs.kubectl; }; helmPkg = lib.mkOption { description = "Place for helm."; type = lib.types.package; default = pkgs.kubernetes-helm; }; talosPkg = lib.mkOption { description = "Place for talosctl."; type = lib.types.package; default = pkgs.talosctl; }; helmfilePkg = lib.mkOption { description = "Place for helmfile"; type = lib.types.package; default = pkgs.helmfile; }; }; }; }; }; } ) ); }; }; config = { apps = lib.mapAttrs ( name: cluster: { type = "app"; program = toString ( pkgs.writeShellScript "apply-${name}" '' # safe measures lol # logic could be better set -e nix build .#${name} cd result # pre-apply # aka dry-run printf "validating " [ -d kube/ ] && \ ${lib.getExe cluster.toolchain.kubePkg} apply \ --dry-run=client --validate=true \ -f kube/ [ -d talos/ ] && \ ${lib.getExe cluster.toolchain.talosPkg} config validate \ --file talos/ [ -d helmfile/ ] && \ ${lib.getExe cluster.toolchain.helmfilePkg} lint # apply # !!!! printf "applying 🤓" [ -d kube/ ] && \ ${lib.getExe cluster.toolchain.kubePkg} apply -f kube/ [ -d helm/ ] && \ ${lib.getExe cluster.toolchain.helmPkg} upgrade --install \ --atomic --cleanup-on-fail --timeout 5m \ "${name}" ./helm/ [ -d talos/ ] && \ ${lib.getExe cluster.toolchain.talosPkg} apply-config -f talos/ [ -d helmfile/ ] && \ ${lib.getExe cluster.toolchain.helmfilePkg} apply '' ); } ) config.kubeClusters; packages = lib.mapAttrs ( name: cluster: pkgs.symlinkJoin { name = "kube-cluster-${name}"; paths = lib.concatMap ( obj: lib.toList ( ( import ./generators { inherit lib ; } pkgs ).${ obj.type } obj.content ) ) cluster.objects; } ) config.kubeClusters; }; } ); }; }