diff --git a/README.md b/README.md index 787d5bb..78ceadf 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ The second step is to find a name for this host, it must be unique from the othe ## Download the keys -The public SSH keys of `host02` have to be saved to `keys/machines/host02.keys`, preferably only the `ssh-ed25519` one. +The public SSH keys of `host02` have to be saved to `keys`, preferably only the `ssh-ed25519` one. It can be retreived with : @@ -91,11 +91,9 @@ The general metadata is declared in `meta/nodes.nix`, the main values to declare Create the directory `secrets` in the configuration folder, and add a `secrets.nix` file containing : ```nix -let - lib = import ../../../lib { }; -in - -lib.setDefault { publicKeys = lib.getNodeKeys "host02"; } [ ] +(import ../../../keys).mkSecrets [ "host02" ] [ + # List of secrets for host02 +] ``` This will be used for future secret management. diff --git a/hive.nix b/hive.nix index 3835df9..9917839 100644 --- a/hive.nix +++ b/hive.nix @@ -5,7 +5,7 @@ let sources = builtins.mapAttrs (patch.base { pkgs = import sources'.nixos-unstable { }; }) .applyPatches' sources'; - lib = import (sources.nix-lib + "/src/trivial.nix"); + nix-lib = import ./lib/nix-lib; patch = import ./lib/nix-patches { patchFile = ./patches; }; @@ -14,15 +14,12 @@ let mkNode = node: { # Import the base configuration for each node - imports = builtins.map (lib.mkRel (./machines/${node})) [ - "_configuration.nix" - "_hardware-configuration.nix" - ]; + imports = [ ./machines/${node}/_configuration.nix ]; }; nixpkgs' = import ./meta/nixpkgs.nix; # All supported nixpkgs versions, instanciated - nixpkgs = lib.mapSingleFuse mkNixpkgs nixpkgs'.supported; + nixpkgs = nix-lib.mapSingleFuse mkNixpkgs nixpkgs'.supported; # Get the configured nixos version for the node, # defaulting to the one defined in meta/nixpkgs @@ -43,10 +40,8 @@ let # Function to create arguments based on the node # mkArgs = node: rec { - lib = import sources.nix-lib { - inherit (nixpkgs.${version node}) lib; - - keysRoot = ./keys; + lib = nixpkgs.${version node}.lib // { + extra = nix-lib; }; meta = (import ./meta) lib; @@ -57,13 +52,15 @@ in { meta = { - nodeNixpkgs = lib.mapSingleFuse (n: nixpkgs.${version n}) nodes; + nodeNixpkgs = nix-lib.mapSingleFuse (n: nixpkgs.${version n}) nodes; specialArgs = { inherit nixpkgs sources; + + dgn-keys = import ./keys; }; - nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes; + nodeSpecialArgs = nix-lib.mapSingleFuse mkArgs nodes; }; defaults = @@ -113,4 +110,4 @@ in }; }; } -// (lib.mapSingleFuse mkNode nodes) +// (nix-lib.mapSingleFuse mkNode nodes) diff --git a/iso/configuration.nix b/iso/configuration.nix index e055c7d..e7cabf8 100644 --- a/iso/configuration.nix +++ b/iso/configuration.nix @@ -1,7 +1,7 @@ { lib, pkgs, ... }: let - dgn-lib = import ../lib { }; + dgn-keys = import ../keys; dgn-members = (import ../meta lib).organization.groups.root; in @@ -34,7 +34,5 @@ in openssh.enable = true; }; - users.users.root.openssh.authorizedKeys.keyFiles = builtins.map ( - m: dgn-lib.mkRel ../keys "${m}.keys" - ) dgn-members; + users.users.root.openssh.authorizedKeys.keys = dgn-keys.getKeys dgn-members; } diff --git a/keys/catvayor.keys b/keys/catvayor.keys deleted file mode 100644 index 0e95ece..0000000 --- a/keys/catvayor.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA16foz+XzwKwyIR4wFgNIAE3Y7AfXyEsUZFVVz8Rie catvayor@katvayor \ No newline at end of file diff --git a/keys/default.nix b/keys/default.nix new file mode 100644 index 0000000..1f24491 --- /dev/null +++ b/keys/default.nix @@ -0,0 +1,80 @@ +let + _sources = import ../npins; + + meta = import ../meta (import _sources.nixpkgs { }).lib; + + getAttr = flip builtins.getAttr; + + inherit (import ../lib/nix-lib) flip setDefault unique; +in + +rec { + # WARNING: When updating this list, make sure that the nodes and members are alphabetically sorted + # If not, you will face an angry maintainer + _keys = { + # SSH keys of the nodes + bridge01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5bS3iBXz8wycBnTvI5Qi79WLu0h4IVv/EOdKYbP5y7" ]; + compute01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu" ]; + geo01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4" ]; + geo02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket" ]; + krz01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4o65gWOgNrxbSd3kiQIGZUM+YD6kuZOQtblvzUGsfB" ]; + rescue01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJa02Annu8o7ggPjTH/9ttotdNGyghlWfU9E8pnuLUf" ]; + storage01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ" ]; + vault01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW" ]; + web01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5" ]; + web02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+QDE+GgZs6zONHvzRW15BzGJNW69k2BFZgB/Zh/tLX" ]; + + # SSH keys of the DGNum members + catvayor = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA16foz+XzwKwyIR4wFgNIAE3Y7AfXyEsUZFVVz8Rie catvayor@katvayor" + ]; + ecoppens = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGmU7yEOCGuGNt4PlQbzd0Cms1RePpo8yEA7Ij/+TdA" ]; + gdd = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICE7TN5NQKGojNGIeTFiHjLHTDQGT8i05JFqX/zLW2zc" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbkPWWZzOBaRdx4+7xQUgxDwuncSl2fxAeVuYfVUPZ" + ]; + jemagius = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOoxmou5OU74GgpIUkhVt6GiB+O9Jy4ge0TwK5MDFJ2F" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxQX0JLRah3GfIOkua4ZhEJhp5Ykv55RO0SPrSUwCBs5arnALg8gq12YLr09t4bzW/NA9/jn7flhh4S54l4RwBUhmV4JSQhGu71KGhfOj5ZBkDoSyYqzbu206DfZP5eQonSmjfP6XghcWOr/jlBzw9YAAQkFxsQgXEkr4kdn0ZXfZGz6b0t3YUjYIuDNbptFsGz2V9iQVy1vnxrjnLSfc25j4et8z729Vpy4M7oCaE6a6hgon4V1jhVbg43NAE5gu2eYFAPIzO3E7ZI8WjyLu1wtOBClk1f+HMen3Tr+SX2PXmpPGb+I2fAkbzu/C4X/M3+2bL1dYjxuvQhvvpAjxFwmdoXW4gWJ3J/FRiFrKsiAY0rYC+yi8SfacJWCv4EEcV/yQ4gYwpmU9xImLaro6w5cOHGCqrzYqjZc4Wi6AWFGeBSNzNs9PXLgMRWeUyiIDOFnSep2ebZeVjTB16m+o/YDEhE10uX9kCCx3Dy/41iJ1ps7V4JWGFsr0Fqaz8mu8=" + ]; + luj = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower" + ]; + mdebray = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris" + ]; + raito = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0xMwWedkKosax9+7D2OlnMxFL/eV4CvFZLsbLptpXr" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKiXXYkhRh+s7ixZ8rvG8ntIqd6FELQ9hh7HoaHQJRPU" + ]; + thubrecht = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+EZXYziiaynJX99EW8KesnmRTZMof3BoIs3mdEl8L3" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL4M4HKjs4cjRAYRk9pmmI8U0R4+T/jQh6Fxp/i1Eoy" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPM1jpXR7BWQa7Sed7ii3SbvIPRRlKb3G91qC0vOwfJn" + ]; + }; + + getKeys = ls: builtins.concatLists (builtins.map (getAttr _keys) ls); + + mkSecrets = + nodes: setDefault { publicKeys = unique (rootKeys ++ (builtins.concatMap getNodeKeys' nodes)); }; + + getNodeKeys' = + node: + let + names = builtins.foldl' (names: group: names ++ meta.organization.groups.${group}) ( + meta.nodes.${node}.admins ++ [ node ] + ) meta.nodes.${node}.adminGroups; + in + unique (getKeys names); + + getNodeKeys = node: rootKeys ++ getNodeKeys' node; + + # List of keys for the root group + rootKeys = getKeys meta.organization.groups.root; + + # List of 'machine' keys + machineKeys = rootKeys ++ (getKeys (builtins.attrNames meta.nodes)); +} diff --git a/keys/ecoppens.keys b/keys/ecoppens.keys deleted file mode 100644 index 4b5a875..0000000 --- a/keys/ecoppens.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGmU7yEOCGuGNt4PlQbzd0Cms1RePpo8yEA7Ij/+TdA diff --git a/keys/gdd.keys b/keys/gdd.keys deleted file mode 100644 index b5d4e40..0000000 --- a/keys/gdd.keys +++ /dev/null @@ -1,2 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICE7TN5NQKGojNGIeTFiHjLHTDQGT8i05JFqX/zLW2zc -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbkPWWZzOBaRdx4+7xQUgxDwuncSl2fxAeVuYfVUPZ diff --git a/keys/jemagius.keys b/keys/jemagius.keys deleted file mode 100644 index be7b1ed..0000000 --- a/keys/jemagius.keys +++ /dev/null @@ -1,2 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOoxmou5OU74GgpIUkhVt6GiB+O9Jy4ge0TwK5MDFJ2F -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxQX0JLRah3GfIOkua4ZhEJhp5Ykv55RO0SPrSUwCBs5arnALg8gq12YLr09t4bzW/NA9/jn7flhh4S54l4RwBUhmV4JSQhGu71KGhfOj5ZBkDoSyYqzbu206DfZP5eQonSmjfP6XghcWOr/jlBzw9YAAQkFxsQgXEkr4kdn0ZXfZGz6b0t3YUjYIuDNbptFsGz2V9iQVy1vnxrjnLSfc25j4et8z729Vpy4M7oCaE6a6hgon4V1jhVbg43NAE5gu2eYFAPIzO3E7ZI8WjyLu1wtOBClk1f+HMen3Tr+SX2PXmpPGb+I2fAkbzu/C4X/M3+2bL1dYjxuvQhvvpAjxFwmdoXW4gWJ3J/FRiFrKsiAY0rYC+yi8SfacJWCv4EEcV/yQ4gYwpmU9xImLaro6w5cOHGCqrzYqjZc4Wi6AWFGeBSNzNs9PXLgMRWeUyiIDOFnSep2ebZeVjTB16m+o/YDEhE10uX9kCCx3Dy/41iJ1ps7V4JWGFsr0Fqaz8mu8= diff --git a/keys/luj.keys b/keys/luj.keys deleted file mode 100644 index 70c87e3..0000000 --- a/keys/luj.keys +++ /dev/null @@ -1,2 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower diff --git a/keys/machines/bridge01.keys b/keys/machines/bridge01.keys deleted file mode 100644 index f9202b9..0000000 --- a/keys/machines/bridge01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5bS3iBXz8wycBnTvI5Qi79WLu0h4IVv/EOdKYbP5y7 diff --git a/keys/machines/compute01.keys b/keys/machines/compute01.keys deleted file mode 100644 index ba12030..0000000 --- a/keys/machines/compute01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu diff --git a/keys/machines/geo01.keys b/keys/machines/geo01.keys deleted file mode 100644 index e205864..0000000 --- a/keys/machines/geo01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4 diff --git a/keys/machines/geo02.keys b/keys/machines/geo02.keys deleted file mode 100644 index 2dd9741..0000000 --- a/keys/machines/geo02.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket diff --git a/keys/machines/krz01.keys b/keys/machines/krz01.keys deleted file mode 100644 index fc5ba52..0000000 --- a/keys/machines/krz01.keys +++ /dev/null @@ -1,2 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4o65gWOgNrxbSd3kiQIGZUM+YD6kuZOQtblvzUGsfB root@krz01 - diff --git a/keys/machines/rescue01.keys b/keys/machines/rescue01.keys deleted file mode 100644 index b7e8182..0000000 --- a/keys/machines/rescue01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJa02Annu8o7ggPjTH/9ttotdNGyghlWfU9E8pnuLUf diff --git a/keys/machines/storage01.keys b/keys/machines/storage01.keys deleted file mode 100644 index eff8f43..0000000 --- a/keys/machines/storage01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ diff --git a/keys/machines/vault01.keys b/keys/machines/vault01.keys deleted file mode 100644 index 90173ca..0000000 --- a/keys/machines/vault01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW diff --git a/keys/machines/web01.keys b/keys/machines/web01.keys deleted file mode 100644 index e81c999..0000000 --- a/keys/machines/web01.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5 diff --git a/keys/machines/web02.keys b/keys/machines/web02.keys deleted file mode 100644 index 09427ed..0000000 --- a/keys/machines/web02.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+QDE+GgZs6zONHvzRW15BzGJNW69k2BFZgB/Zh/tLX diff --git a/keys/mdebray.keys b/keys/mdebray.keys deleted file mode 100644 index 3f26a23..0000000 --- a/keys/mdebray.keys +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris diff --git a/keys/raito.keys b/keys/raito.keys deleted file mode 100644 index 7a717dd..0000000 --- a/keys/raito.keys +++ /dev/null @@ -1,3 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0xMwWedkKosax9+7D2OlnMxFL/eV4CvFZLsbLptpXr -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKiXXYkhRh+s7ixZ8rvG8ntIqd6FELQ9hh7HoaHQJRPU diff --git a/keys/thubrecht.keys b/keys/thubrecht.keys deleted file mode 100644 index ddeabce..0000000 --- a/keys/thubrecht.keys +++ /dev/null @@ -1,3 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+EZXYziiaynJX99EW8KesnmRTZMof3BoIs3mdEl8L3 -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL4M4HKjs4cjRAYRk9pmmI8U0R4+T/jQh6Fxp/i1Eoy -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPM1jpXR7BWQa7Sed7ii3SbvIPRRlKb3G91qC0vOwfJn diff --git a/lib/default.nix b/lib/default.nix deleted file mode 100644 index 02edb55..0000000 --- a/lib/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -_: - -let - sources = import ../npins; - - lib = import sources.nix-lib { - inherit ((import sources.nixpkgs { })) lib; - - keysRoot = ../keys; - }; - - meta = import ../meta lib; - - inherit (lib.extra) getAllKeys; -in - -lib.extra -// rec { - # Get publickeys associated to a node - getNodeKeys = - node: - let - names = builtins.foldl' (names: group: names ++ meta.organization.groups.${group}) ( - meta.nodes.${node}.admins ++ [ "/machines/${node}" ] - ) meta.nodes.${node}.adminGroups; - in - rootKeys ++ (getAllKeys names); - - rootKeys = getAllKeys meta.organization.groups.root; - - machineKeys = - rootKeys ++ (getAllKeys (builtins.map (n: "machines/${n}") (builtins.attrNames meta.nodes))); -} diff --git a/lib/nix-lib/default.nix b/lib/nix-lib/default.nix new file mode 100644 index 0000000..39e446d --- /dev/null +++ b/lib/nix-lib/default.nix @@ -0,0 +1,197 @@ +# Copyright Tom Hubrecht, (2023) +# +# Tom Hubrecht +# +# This software is governed by the CeCILL license under French law and +# abiding by the rules of distribution of free software. You can use, +# modify and/ or redistribute the software under the terms of the CeCILL +# license as circulated by CEA, CNRS and INRIA at the following URL +# "http://www.cecill.info". +# +# As a counterpart to the access to the source code and rights to copy, +# modify and redistribute granted by the license, users are provided only +# with a limited warranty and the software's author, the holder of the +# economic rights, and the successive licensors have only limited +# liability. +# +# In this respect, the user's attention is drawn to the risks associated +# with loading, using, modifying and/or developing or reproducing the +# software by the user in light of its specific status of free software, +# that may mean that it is complicated to manipulate, and that also +# therefore means that it is reserved for developers and experienced +# professionals having in-depth computer knowledge. Users are therefore +# encouraged to load and test the software's suitability as regards their +# requirements in conditions enabling the security of their systems and/or +# data to be ensured and, more generally, to use and operate it in the +# same conditions as regards security. +# +# The fact that you are presently reading this means that you have had +# knowledge of the CeCILL license and that you accept its terms. + +let + # Reimplement optional functions + _optional = + default: b: value: + if b then value else default; +in + +rec { + inherit (import ./nixpkgs.nix) + flip + hasPrefix + recursiveUpdate + splitString + unique + ; + + /* + Fuses a list of attribute sets into a single attribute set. + + Type: [attrs] -> attrs + + Example: + x = [ { a = 1; } { b = 2; } ] + fuseAttrs x + => { a = 1; b = 2; } + */ + fuseAttrs = builtins.foldl' (attrs: x: attrs // x) { }; + + fuseValueAttrs = attrs: fuseAttrs (builtins.attrValues attrs); + + /* + Applies a function to `attrsList` before fusing the resulting list + of attribute sets. + + Type: ('a -> attrs) -> ['a] -> attrs + + Example: + x = [ "to" "ta" "ti" ] + f = s: { ${s} = s + s; } + mapFuse f x + => { to = "toto"; ta = "tata"; ti = "titi"; } + */ + mapFuse = + # 'a -> attrs + f: + # ['a] + attrsList: + fuseAttrs (builtins.map f attrsList); + + /* + Equivalent of lib.singleton but for an attribute set. + + Type: str -> 'a -> attrs + + Example: + singleAttr "a" 1 + => { a = 1; } + */ + singleAttr = name: value: { ${name} = value; }; + + # Enables a list of modules. + enableAttrs' = + enable: + mapFuse (m: { + ${m}.${enable} = true; + }); + + enableModules = enableAttrs' "enable"; + + /* + Create an attribute set from a list of values, mapping those + values through the function `f`. + + Example: + mapSingleFuse (x: "val-${x}") [ "a" "b" ] + => { a = "val-a"; b = "val-b" } + */ + mapSingleFuse = f: mapFuse (x: singleAttr x (f x)); + + /* + Creates a relative path as a string + + Type: path -> str -> path + + Example: + mkRel /home/test/ "file.txt" + => "/home/test/file.txt" + */ + mkRel = path: file: path + "/${file}"; + + setDefault = + default: + mapFuse (name: { + ${name} = default; + }); + + mkBaseSecrets = + root: + mapFuse (secret: { + ${secret}.file = mkRel root secret; + }); + + getSecrets = dir: builtins.attrNames (import (mkRel dir "secrets.nix")); + + subAttr = attrs: name: attrs.${name}; + + subAttrs = attrs: builtins.map (subAttr attrs); + + optionalList = _optional [ ]; + + optionalAttrs = _optional { }; + + optionalString = _optional ""; + /* + Same as fuseAttrs but using `lib.recursiveUpdate` to merge attribute + sets together. + + Type: [attrs] -> attrs + */ + recursiveFuse = builtins.foldl' recursiveUpdate { }; + + mkImport = + root: file: + let + path = mkRel root file; + in + path + (optionalString (!(builtins.pathExists path)) ".nix"); + + mkImports = root: builtins.map (mkImport root); + + /* + Creates a confugiration by merging enabled modules, + services and extraConfig. + + Example: + mkConfig { + enabledModules = [ "ht-defaults" ]; + enabledServices = [ "toto" ]; + extraConfig = { services.nginx.enable = true; }; + root = ./.; + } + => + { + imports = [ ./toto ]; + ht-defaults.enable = true; + services.nginx.enable = true; + } + */ + mkConfig = + { + # List of modules to enable with `enableModules` + enabledModules, + # List of services to import + enabledServices, + # Extra configuration, defaults to `{ }` + extraConfig ? { }, + # Path relative to which the enabled services will be imported + root, + }: + recursiveFuse [ + (enableModules enabledModules) + + { imports = mkImports root ([ "_hardware-configuration" ] ++ enabledServices); } + + extraConfig + ]; +} diff --git a/lib/nix-lib/nixpkgs.nix b/lib/nix-lib/nixpkgs.nix new file mode 100644 index 0000000..302a1b9 --- /dev/null +++ b/lib/nix-lib/nixpkgs.nix @@ -0,0 +1,416 @@ +### +# Collection of nixpkgs library functions, those are necessary for defining our own lib +# +# They have been simplified and builtins are used in some places, instead of lib shims. + +rec { + /** + Does the same as the update operator '//' except that attributes are + merged until the given predicate is verified. The predicate should + accept 3 arguments which are the path to reach the attribute, a part of + the first attribute set and a part of the second attribute set. When + the predicate is satisfied, the value of the first attribute set is + replaced by the value of the second attribute set. + + # Inputs + + `pred` + + : Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments. + + `lhs` + + : Left attribute set of the merge. + + `rhs` + + : Right attribute set of the merge. + + # Type + + ``` + recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet + ``` + + # Examples + :::{.example} + ## `lib.attrsets.recursiveUpdateUntil` usage example + + ```nix + recursiveUpdateUntil (path: l: r: path == ["foo"]) { + # first attribute set + foo.bar = 1; + foo.baz = 2; + bar = 3; + } { + #second attribute set + foo.bar = 1; + foo.quz = 2; + baz = 4; + } + + => { + foo.bar = 1; # 'foo.*' from the second set + foo.quz = 2; # + bar = 3; # 'bar' from the first set + baz = 4; # 'baz' from the second set + } + ``` + + ::: + */ + recursiveUpdateUntil = + pred: lhs: rhs: + let + f = + attrPath: + builtins.zipAttrsWith ( + n: values: + let + here = attrPath ++ [ n ]; + in + if builtins.length values == 1 || pred here (builtins.elemAt values 1) (builtins.head values) then + builtins.head values + else + f here values + ); + in + f [ ] [ + rhs + lhs + ]; + + /** + A recursive variant of the update operator ‘//’. The recursion + stops when one of the attribute values is not an attribute set, + in which case the right hand side value takes precedence over the + left hand side value. + + # Inputs + + `lhs` + + : Left attribute set of the merge. + + `rhs` + + : Right attribute set of the merge. + + # Type + + ``` + recursiveUpdate :: AttrSet -> AttrSet -> AttrSet + ``` + + # Examples + :::{.example} + ## `lib.attrsets.recursiveUpdate` usage example + + ```nix + recursiveUpdate { + boot.loader.grub.enable = true; + boot.loader.grub.device = "/dev/hda"; + } { + boot.loader.grub.device = ""; + } + + returns: { + boot.loader.grub.enable = true; + boot.loader.grub.device = ""; + } + ``` + + ::: + */ + recursiveUpdate = + lhs: rhs: + recursiveUpdateUntil ( + _: lhs: rhs: + !(builtins.isAttrs lhs && builtins.isAttrs rhs) + ) lhs rhs; + + /** + Determine whether a string has given prefix. + + # Inputs + + `pref` + : Prefix to check for + + `str` + : Input string + + # Type + + ``` + hasPrefix :: string -> string -> bool + ``` + + # Examples + :::{.example} + ## `lib.strings.hasPrefix` usage example + + ```nix + hasPrefix "foo" "foobar" + => true + hasPrefix "foo" "barfoo" + => false + ``` + + ::: + */ + hasPrefix = pref: str: (builtins.substring 0 (builtins.stringLength pref) str == pref); + + /** + Escape occurrence of the elements of `list` in `string` by + prefixing it with a backslash. + + # Inputs + + `list` + : 1\. Function argument + + `string` + : 2\. Function argument + + # Type + + ``` + escape :: [string] -> string -> string + ``` + + # Examples + :::{.example} + ## `lib.strings.escape` usage example + + ```nix + escape ["(" ")"] "(foo)" + => "\\(foo\\)" + ``` + + ::: + */ + escape = list: builtins.replaceStrings list (builtins.map (c: "\\${c}") list); + + /** + Convert a string `s` to a list of characters (i.e. singleton strings). + This allows you to, e.g., map a function over each character. However, + note that this will likely be horribly inefficient; Nix is not a + general purpose programming language. Complex string manipulations + should, if appropriate, be done in a derivation. + Also note that Nix treats strings as a list of bytes and thus doesn't + handle unicode. + + # Inputs + + `s` + : 1\. Function argument + + # Type + + ``` + stringToCharacters :: string -> [string] + ``` + + # Examples + :::{.example} + ## `lib.strings.stringToCharacters` usage example + + ```nix + stringToCharacters "" + => [ ] + stringToCharacters "abc" + => [ "a" "b" "c" ] + stringToCharacters "🦄" + => [ "�" "�" "�" "�" ] + ``` + + ::: + */ + stringToCharacters = s: builtins.genList (p: builtins.substring p 1 s) (builtins.stringLength s); + + /** + Turn a string `s` into an exact regular expression + + # Inputs + + `s` + : 1\. Function argument + + # Type + + ``` + escapeRegex :: string -> string + ``` + + # Examples + :::{.example} + ## `lib.strings.escapeRegex` usage example + + ```nix + escapeRegex "[^a-z]*" + => "\\[\\^a-z]\\*" + ``` + + ::: + */ + escapeRegex = escape (stringToCharacters "\\[{()^$?*+|."); + + /** + Appends string context from string like object `src` to `target`. + + :::{.warning} + This is an implementation + detail of Nix and should be used carefully. + ::: + + Strings in Nix carry an invisible `context` which is a list of strings + representing store paths. If the string is later used in a derivation + attribute, the derivation will properly populate the inputDrvs and + inputSrcs. + + # Inputs + + `src` + : The string to take the context from. If the argument is not a string, + it will be implicitly converted to a string. + + `target` + : The string to append the context to. If the argument is not a string, + it will be implicitly converted to a string. + + # Type + + ``` + addContextFrom :: string -> string -> string + ``` + + # Examples + :::{.example} + ## `lib.strings.addContextFrom` usage example + + ```nix + pkgs = import { }; + addContextFrom pkgs.coreutils "bar" + => "bar" + ``` + + The context can be displayed using the `toString` function: + + ```nix + nix-repl> builtins.getContext (lib.strings.addContextFrom pkgs.coreutils "bar") + { + "/nix/store/m1s1d2dk2dqqlw3j90jl3cjy2cykbdxz-coreutils-9.5.drv" = { ... }; + } + ``` + + ::: + */ + addContextFrom = src: target: builtins.substring 0 0 src + target; + + /** + Cut a string with a separator and produces a list of strings which + were separated by this separator. + + # Inputs + + `sep` + : 1\. Function argument + + `s` + : 2\. Function argument + + # Type + + ``` + splitString :: string -> string -> [string] + ``` + + # Examples + :::{.example} + ## `lib.strings.splitString` usage example + + ```nix + splitString "." "foo.bar.baz" + => [ "foo" "bar" "baz" ] + splitString "/" "/usr/local/bin" + => [ "" "usr" "local" "bin" ] + ``` + + ::: + */ + splitString = + sep: s: + let + splits = builtins.filter builtins.isString ( + builtins.split (escapeRegex (builtins.toString sep)) (builtins.toString s) + ); + in + builtins.map (addContextFrom s) splits; + + /** + Remove duplicate elements from the `list`. O(n^2) complexity. + + # Inputs + + `list` + + : Input list + + # Type + + ``` + unique :: [a] -> [a] + ``` + + # Examples + :::{.example} + ## `lib.lists.unique` usage example + + ```nix + unique [ 3 2 3 4 ] + => [ 3 2 4 ] + ``` + + ::: + */ + unique = builtins.foldl' (acc: e: if builtins.elem e acc then acc else acc ++ [ e ]) [ ]; + + /** + Flip the order of the arguments of a binary function. + + # Inputs + + `f` + + : 1\. Function argument + + `a` + + : 2\. Function argument + + `b` + + : 3\. Function argument + + # Type + + ``` + flip :: (a -> b -> c) -> (b -> a -> c) + ``` + + # Examples + :::{.example} + ## `lib.trivial.flip` usage example + + ```nix + flip concat [1] [2] + => [ 2 1 ] + ``` + + ::: + */ + flip = + f: a: b: + f b a; +} diff --git a/machines/bridge01/secrets/secrets.nix b/machines/bridge01/secrets/secrets.nix index c504d17..905f411 100644 --- a/machines/bridge01/secrets/secrets.nix +++ b/machines/bridge01/secrets/secrets.nix @@ -1,5 +1,3 @@ -let - lib = import ../../../lib { }; -in - -lib.setDefault { publicKeys = lib.getNodeKeys "bridge01"; } [ ] +(import ../../../keys).mkSecrets [ "bridg01" ] [ + # List of secrets for bridge01 +] diff --git a/machines/compute01/kanidm/secrets/secrets.nix b/machines/compute01/kanidm/secrets/secrets.nix index 3d54c1b..ef60ece 100644 --- a/machines/compute01/kanidm/secrets/secrets.nix +++ b/machines/compute01/kanidm/secrets/secrets.nix @@ -1,9 +1,4 @@ -let - lib = import ../../../../lib { }; - publicKeys = lib.getNodeKeys "compute01"; -in - -lib.setDefault { inherit publicKeys; } [ +(import ../../../../keys).mkSecrets [ "compute01" ] [ "kanidm-password_admin" "kanidm-password_idm_admin" ] diff --git a/machines/compute01/secrets/secrets.nix b/machines/compute01/secrets/secrets.nix index c29f27f..9af2cdd 100644 --- a/machines/compute01/secrets/secrets.nix +++ b/machines/compute01/secrets/secrets.nix @@ -1,9 +1,5 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "compute01"; -in - -lib.setDefault { inherit publicKeys; } [ +(import ../../../keys).mkSecrets [ "compute01" ] [ + # List of secrets for compute01 "arkheon-env_file" "bupstash-put_key" "dgsi-email_host_password_file" diff --git a/machines/geo01/secrets/secrets.nix b/machines/geo01/secrets/secrets.nix index c459051..39d4f29 100644 --- a/machines/geo01/secrets/secrets.nix +++ b/machines/geo01/secrets/secrets.nix @@ -1,5 +1,3 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "geo01"; -in -lib.setDefault { inherit publicKeys; } [ ] +(import ../../../keys).mkSecrets [ "geo01" ] [ + # List of secrets for geo01 +] diff --git a/machines/geo02/secrets/secrets.nix b/machines/geo02/secrets/secrets.nix index bac045d..429d1a7 100644 --- a/machines/geo02/secrets/secrets.nix +++ b/machines/geo02/secrets/secrets.nix @@ -1,5 +1,3 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "geo02"; -in -lib.setDefault { inherit publicKeys; } [ ] +(import ../../../keys).mkSecrets [ "geo02" ] [ + # List of secrets for geo02 +] diff --git a/machines/krz01/secrets/secrets.nix b/machines/krz01/secrets/secrets.nix index 057ed28..45004b9 100644 --- a/machines/krz01/secrets/secrets.nix +++ b/machines/krz01/secrets/secrets.nix @@ -1,5 +1,3 @@ -let - lib = import ../../../lib { }; -in - -lib.setDefault { publicKeys = lib.getNodeKeys "krz01"; } [ ] +(import ../../../keys).mkSecrets [ "krz01" ] [ + # List of secrets for krz01 +] diff --git a/machines/rescue01/secrets/secrets.nix b/machines/rescue01/secrets/secrets.nix index 8da8fb3..4cc5cdd 100644 --- a/machines/rescue01/secrets/secrets.nix +++ b/machines/rescue01/secrets/secrets.nix @@ -1,5 +1,4 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "rescue01"; -in -lib.setDefault { inherit publicKeys; } [ "stateless-uptime-kuma-password" ] +(import ../../../keys).mkSecrets [ "rescue01" ] [ + # List of secrets for rescue01 + "stateless-uptime-kuma-password" +] diff --git a/machines/storage01/secrets/secrets.nix b/machines/storage01/secrets/secrets.nix index 58a3be1..7004cdf 100644 --- a/machines/storage01/secrets/secrets.nix +++ b/machines/storage01/secrets/secrets.nix @@ -1,8 +1,5 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "storage01"; -in -lib.setDefault { inherit publicKeys; } [ +(import ../../../keys).mkSecrets [ "storage01" ] [ + # List of secrets for storage01 "bupstash-put_key" "forgejo-mailer_password_file" "forgejo_runners-token_file" diff --git a/machines/vault01/secrets/secrets.nix b/machines/vault01/secrets/secrets.nix index 1120df5..cd300fd 100644 --- a/machines/vault01/secrets/secrets.nix +++ b/machines/vault01/secrets/secrets.nix @@ -1,8 +1,5 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "vault01"; -in -lib.setDefault { inherit publicKeys; } [ +(import ../../../keys).mkSecrets [ "vault01" ] [ + # List of secrets for vault01 "radius-auth_token_file" "radius-ca_pem_file" "radius-cert_pem_file" diff --git a/machines/web01/secrets/secrets.nix b/machines/web01/secrets/secrets.nix index cb8bce0..ed65294 100644 --- a/machines/web01/secrets/secrets.nix +++ b/machines/web01/secrets/secrets.nix @@ -1,8 +1,5 @@ -let - lib = import ../../../lib { }; - publicKeys = lib.getNodeKeys "web01"; -in -lib.setDefault { inherit publicKeys; } [ +(import ../../../keys).mkSecrets [ "web01" ] [ + # List of secrets for web01 "acme-certs_secret" "bupstash-put_key" "matterbridge-config_file" diff --git a/machines/web02/secrets/secrets.nix b/machines/web02/secrets/secrets.nix index fe09fdd..6c96a1b 100644 --- a/machines/web02/secrets/secrets.nix +++ b/machines/web02/secrets/secrets.nix @@ -1,7 +1,5 @@ -let - lib = import ../../../lib { }; -in -lib.setDefault { publicKeys = lib.getNodeKeys "web02"; } [ +(import ../../../keys).mkSecrets [ "web02" ] [ + # List of secrets for web02 "cas_eleves-secret_key_file" "kadenios-secret_key_file" "kadenios-email_password_file" diff --git a/meta/options.nix b/meta/options.nix index 7bae727..cf7476b 100644 --- a/meta/options.nix +++ b/meta/options.nix @@ -368,10 +368,10 @@ in name: "A member of the external service ${name} admins was not found in the members list." ) org.external) - # Check that all members have a keyFile + # Check that all members have ssh keys (builtins.map (name: { - assertion = builtins.pathExists "${builtins.toString ../keys}/${name}.keys"; - message = "No ssh keys file found for ${name}."; + assertion = ((import ../keys)._keys.${name} or [ ]) != [ ]; + message = "No ssh keys found for ${name}."; }) members) ]; }; diff --git a/meta/verify.nix b/meta/verify.nix index 92b9234..ecf2ed2 100644 --- a/meta/verify.nix +++ b/meta/verify.nix @@ -5,12 +5,6 @@ let pkgs = import sources.nixpkgs { }; dns = import sources."dns.nix" { inherit pkgs; }; - - lib = import sources.nix-lib { - inherit (pkgs) lib; - - keysRoot = ../keys; - }; in { @@ -29,6 +23,14 @@ in pkgs.writers.writeJSON "meta.json" config; dns = dns.util.writeZone "dgnum.eu" ( - pkgs.lib.recursiveUpdate { SOA.serial = 0; } (import ./dns.nix { inherit dns lib; }) + pkgs.lib.recursiveUpdate { SOA.serial = 0; } ( + import ./dns.nix { + inherit dns; + + lib = pkgs.lib // { + extra = import ../lib/nix-lib; + }; + } + ) ); } diff --git a/modules/dgn-access-control.nix b/modules/dgn-access-control.nix index 375ea9c..df618f2 100644 --- a/modules/dgn-access-control.nix +++ b/modules/dgn-access-control.nix @@ -34,6 +34,7 @@ { config, lib, + dgn-keys, meta, nodeMeta, ... @@ -83,7 +84,7 @@ in dgn-access-control.users.root = mkDefault admins; users.users = builtins.mapAttrs (_: members: { - openssh.authorizedKeys.keys = lib.extra.getAllKeys members; + openssh.authorizedKeys.keys = dgn-keys.getKeys members; }) cfg.users; }; } diff --git a/modules/dgn-backups/default.nix b/modules/dgn-backups/default.nix index 3ec46d8..894f4e8 100644 --- a/modules/dgn-backups/default.nix +++ b/modules/dgn-backups/default.nix @@ -1,6 +1,7 @@ { config, lib, + dgn-keys, name, ... }: @@ -103,15 +104,12 @@ in access = [ { repo = "default"; - keys = lib.extra.getAllKeys ( - # Nodes allowed to create backups - builtins.map (host: "machines/${host}") [ - "compute01" - "storage01" - "vault01" - "web01" - ] - ); + keys = dgn-keys.getKeys [ + "compute01" + "storage01" + "vault01" + "web01" + ]; allowed = [ "put" ]; } ]; @@ -121,8 +119,7 @@ in }; programs.ssh.knownHosts = - lib.extra.mapFuse - (host: { "${host}.dgnum".publicKey = builtins.head (lib.extra.getKeys "machines/${host}"); }) + lib.extra.mapFuse (host: { "${host}.dgnum".publicKey = builtins.head dgn-keys._keys.${host}; }) [ "compute01" "geo01" diff --git a/modules/dgn-backups/keys/secrets.nix b/modules/dgn-backups/keys/secrets.nix index 0d9d49b..66cf873 100644 --- a/modules/dgn-backups/keys/secrets.nix +++ b/modules/dgn-backups/keys/secrets.nix @@ -1,8 +1,4 @@ -let - lib = import ../../../lib { }; -in - -lib.setDefault { publicKeys = lib.rootKeys; } [ +(import ../../../keys).mkSecrets [ ] [ "compute01.key" "storage01.key" "web01.key" diff --git a/modules/dgn-netbox-agent/secrets.nix b/modules/dgn-netbox-agent/secrets.nix index f72bc03..ebab356 100644 --- a/modules/dgn-netbox-agent/secrets.nix +++ b/modules/dgn-netbox-agent/secrets.nix @@ -1 +1 @@ -{ netbox-agent.publicKeys = (import ../../lib { }).machineKeys; } +{ netbox-agent.publicKeys = (import ../../keys).machineKeys; } diff --git a/modules/dgn-notify/secrets.nix b/modules/dgn-notify/secrets.nix index 193c851..d6e3e80 100644 --- a/modules/dgn-notify/secrets.nix +++ b/modules/dgn-notify/secrets.nix @@ -1 +1 @@ -{ mail.publicKeys = (import ../../lib { }).machineKeys; } +{ mail.publicKeys = (import ../../keys).machineKeys; } diff --git a/modules/dgn-records/secrets.nix b/modules/dgn-records/secrets.nix index deac3e6..68a82cd 100644 --- a/modules/dgn-records/secrets.nix +++ b/modules/dgn-records/secrets.nix @@ -1 +1 @@ -{ __arkheon-token_file.publicKeys = (import ../../lib { }).machineKeys; } +{ __arkheon-token_file.publicKeys = (import ../../keys).machineKeys; } diff --git a/npins/sources.json b/npins/sources.json index 7b7d6e6..fa089ef 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -194,20 +194,6 @@ "url": "https://github.com/RaitoBezarius/microvm.nix/archive/49899c9a4fdf75320785e79709bf1608c34caeb8.tar.gz", "hash": "0sz6azdpiz4bd36x23bcdhx6mwyqj8zl5cczjgv48xqfmysy8zwy" }, - "nix-lib": { - "type": "GitRelease", - "repository": { - "type": "Git", - "url": "https://git.hubrecht.ovh/hubrecht/nix-lib" - }, - "pre_releases": false, - "version_upper_bound": null, - "release_prefix": null, - "version": "0.1.6", - "revision": "ffb3dfa4c146d48300bd4fa625acfe48e091a734", - "url": null, - "hash": "1frsja071qqx6p7rjnijzhidqfylx0ipzqpmjdvj4jl89h34vrhr" - }, "nix-modules": { "type": "Git", "repository": {