--- a/lib/default.nix +++ b/lib/default.nix @@ -5,7 +5,7 @@ in rec { root = nixpkgs.lib.evalModules { - modules = (import ../modules/modules.nix { inherit data; }) ++ [ config ]; + modules = (import ../modules/fleet/_modules.nix) ++ [ config data ]; specialArgs = { inherit nixpkgs; fleet = import ./fleetLib.nix { --- /dev/null +++ b/modules/fleet/_modules.nix @@ -0,0 +1,4 @@ +[ + ./meta.nix + ./secrets.nix +] --- /dev/null +++ b/modules/fleet/meta.nix @@ -0,0 +1,40 @@ +{ lib, fleet, config, ... }: with lib; +let + host = with types; { + options = { + modules = mkOption { + type = listOf anything; + description = "List of nixos modules"; + default = [ ]; + }; + system = mkOption { + type = str; + description = "Type of system"; + }; + encryptionKey = mkOption { + type = str; + description = "Encryption key"; + }; + }; + }; +in +{ + options = with types; { + hosts = mkOption { + type = attrsOf (submodule host); + default = { }; + description = "Configurations of individual hosts"; + }; + globalModules = mkOption { + type = listOf anything; + description = "Modules, which should be added to every system"; + default = [ ]; + }; + }; + config = { + hosts = fleet.hostsToAttrs (host: { + modules = config.globalModules; + }); + globalModules = import ../nixos/_modules.nix; + }; +} --- /dev/null +++ b/modules/fleet/secrets.nix @@ -0,0 +1,86 @@ +{ lib, fleet, config, ... }: with lib; +let + sharedSecret = with types; { + options = { + owners = mkOption { + type = listOf str; + description = '' + List of hosts to encrypt secret for + + Secrets would be decrypted and stored to /run/secrets/$\{name} on owners + ''; + }; + generator = mkOption { + type = package; + description = "Derivation to execute for secret generation"; + }; + expireIn = mkOption { + type = nullOr int; + description = "Time in hours, in which this secret should be regenerated"; + default = null; + }; + public = mkOption { + type = nullOr str; + description = "Secret public data"; + default = null; + }; + secret = mkOption { + type = str; + description = "Encrypted secret data"; + }; + }; + }; + hostSecret = with types; { + options = { + generator = mkOption { + type = package; + description = "Derivation to execute for secret generation"; + }; + expireIn = mkOption { + type = nullOr int; + description = "Time in hours, in which this secret should be regenerated"; + default = null; + }; + public = mkOption { + type = nullOr str; + description = "Secret public data"; + default = null; + }; + secret = mkOption { + type = str; + description = "Encrypted secret data"; + }; + }; + }; +in +{ + options = with types; { + sharedSecrets = mkOption { + type = attrsOf (submodule sharedSecret); + default = { }; + description = "Shared secrets"; + }; + hostSecrets = mkOption { + type = attrsOf (attrsOf (submodule hostSecret)); + default = { }; + description = "Host secrets"; + }; + }; + config = with fleet; { + hosts = hostsToAttrs (host: { + modules = + let + cleanupSecret = (secretName: v: { + inherit (v) public secret; + }); + in + [ + { + secrets = (mapAttrs cleanupSecret + (filterAttrs (_: v: builtins.elem host v.owners) config.sharedSecrets) + ) // (mapAttrs cleanupSecret (if config.hostSecrets ? host then config.hostSecrets.${host} else {})); + } + ]; + }); + }; +} --- a/modules/hosts.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ lib, fleet, ... }: with lib; -let - host = with types; { - options = { - modules = mkOption { - type = listOf anything; - description = "List of nixos modules"; - default = [ ]; - }; - network = mkOption { - type = submodule { - options = { - fleetIp = { - type = str; - description = "Ip which is available to all hosts in fleet"; - }; - }; - }; - description = "Network definition of host"; - }; - system = mkOption { - type = str; - description = "Type of system"; - }; - encryptionKey = mkOption { - type = str; - description = "Encryption key"; - }; - }; - }; -in -{ - options = with types; { - hosts = mkOption { - type = attrsOf (submodule host); - default = { }; - description = "Configurations of individual hosts"; - }; - }; - config.hosts = fleet.hostsToAttrs (host: { - modules = [ - ({ ... }: { - nixpkgs.overlays = [ (import ../pkgs) ]; - }) - ]; - }); -} --- a/modules/modules.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ data }: [ - ./hosts.nix - ./secrets - data -] --- /dev/null +++ b/modules/nixos/_modules.nix @@ -0,0 +1,5 @@ +[ + ./fleetPkgs.nix + ./meta.nix + ./secrets.nix +] --- /dev/null +++ b/modules/nixos/fleetPkgs.nix @@ -0,0 +1 @@ +{ ... }: { nixpkgs.overlays = [ (import ../../pkgs) ]; } --- /dev/null +++ b/modules/nixos/meta.nix @@ -0,0 +1,32 @@ +{ lib, ... }: +with lib; +{ + options = with types; { + tags = mkOption { + type = listOf str; + description = "Host tags"; + default = [ ]; + }; + network = mkOption { + type = submodule { + options = { + internalIps = mkOption { + type = listOf str; + description = "Internal ips"; + default = [ ]; + }; + externalIps = mkOption { + type = listOf str; + description = "External ips"; + default = [ ]; + }; + }; + }; + description = "Network definition of host"; + }; + }; + config = { + tags = [ "all" ]; + network = { }; + }; +} --- /dev/null +++ b/modules/nixos/secrets.nix @@ -0,0 +1,60 @@ +{ lib, config, pkgs, ... }: with lib; +let + sysConfig = config; + secretType = types.submodule ({ config, ... }: { + config = { + path = mkOptionDefault "/run/secrets/${config._module.args.name}"; + }; + options = { + public = mkOption { + type = types.nullOr types.str; + description = "Secret public data"; + default = null; + }; + secret = mkOption { + type = types.str; + description = "Encrypted secret data"; + }; + mode = mkOption { + type = types.str; + description = "Secret mode"; + default = "0440"; + }; + owner = mkOption { + type = types.str; + description = "Owner of the secret"; + default = "root"; + }; + group = mkOption { + type = types.str; + description = "Group of the secret"; + default = sysConfig.users.users.${config.owner}.group; + }; + + path = mkOption { + type = types.str; + readOnly = true; + description = "Path to the decrypted secret"; + }; + }; + }); + secretsFile = pkgs.writeTextFile { + name = "secrets.json"; + text = builtins.toJSON config.secrets; + }; +in +{ + options = { + secrets = mkOption { + type = types.attrsOf secretType; + default = { }; + description = "Host-local secrets"; + }; + }; + config = { + system.activationScripts.decryptSecrets = '' + 1>&2 echo "setting up secrets" + ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets ${secretsFile} + ''; + }; +} --- a/modules/secrets/default.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ lib, fleet, config, ... }: with lib; -let - secret = with types; { - options = { - owners = mkOption { - type = listOf str; - description = '' - List of hosts to encrypt secret for - - Secrets would be decrypted and stored to /run/secrets/$\{name} on owners - ''; - }; - generator = mkOption { - type = package; - description = "Derivation to execute for secret generation"; - }; - expireIn = mkOption { - type = nullOr int; - description = "Time in hours, in which this secret should be regenerated"; - default = null; - }; - public = mkOption { - type = nullOr str; - description = "Secret public data"; - default = null; - }; - secret = mkOption { - type = str; - description = "Encrypted secret data"; - }; - }; - }; -in -{ - options = with types; { - secrets = mkOption { - type = attrsOf (submodule secret); - default = { }; - description = "Secrets"; - }; - }; - config = with fleet; { - hosts = hostsToAttrs (host: { - modules = [ - ./nixosModule.nix - { - secrets = mapAttrs - (secretName: v: { - inherit (v) public secret; - }) - (filterAttrs (_: v: builtins.elem host v.owners) config.secrets); - } - ]; - }); - }; -} --- a/modules/secrets/nixosModule.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ lib, config, pkgs, ... }: with lib; -let - sysConfig = config; - secretType = types.submodule ({ config, ... }: { - config = { - path = mkOptionDefault "/run/secrets/${config._module.args.name}"; - }; - options = { - public = mkOption { - type = types.nullOr types.str; - description = "Secret public data"; - default = null; - }; - secret = mkOption { - type = types.str; - description = "Encrypted secret data"; - }; - mode = mkOption { - type = types.str; - description = "Secret mode"; - default = "0440"; - }; - owner = mkOption { - type = types.str; - description = "Owner of the secret"; - default = "root"; - }; - group = mkOption { - type = types.str; - description = "Group of the secret"; - default = sysConfig.users.users.${config.owner}.group; - }; - - path = mkOption { - type = types.str; - readOnly = true; - description = "Path to the decrypted secret"; - }; - }; - }); - secretsFile = pkgs.writeTextFile { - name = "secrets.json"; - text = builtins.toJSON config.secrets; - }; -in -{ - options = { - secrets = mkOption { - type = types.attrsOf secretType; - default = { }; - description = "Host-local secrets"; - }; - }; - config = { - system.activationScripts.decryptSecrets = '' - 1>&2 echo "setting up secrets" - ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets ${secretsFile} - ''; - }; -}