From dd91691177077ec8ed66802db305643bcbfcc10f Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Wed, 23 Jun 2021 10:24:44 -0400
Subject: [PATCH] Adapt storage nodes to value-based approach

---
 morph/grid/local/grid.nix       |  30 ++++-----
 morph/grid/production/grid.nix  |  99 +++++++++++++++++------------
 morph/grid/testing/grid.nix     |  15 ++---
 morph/lib/customize-storage.nix |  23 +++++++
 morph/lib/default.nix           |   5 +-
 morph/lib/make-storage.nix      | 109 --------------------------------
 morph/lib/make-testing.nix      |  80 -----------------------
 morph/lib/storage.nix           |  78 +++++++++++++++++++++++
 8 files changed, 184 insertions(+), 255 deletions(-)
 create mode 100644 morph/lib/customize-storage.nix
 delete mode 100644 morph/lib/make-storage.nix
 delete mode 100644 morph/lib/make-testing.nix
 create mode 100644 morph/lib/storage.nix

diff --git a/morph/grid/local/grid.nix b/morph/grid/local/grid.nix
index 64c83da5..14335526 100644
--- a/morph/grid/local/grid.nix
+++ b/morph/grid/local/grid.nix
@@ -30,23 +30,21 @@ in lib.make-grid {
       ];
     };
 
-    "storage1" = lib.make-testing (cfg // rec {
-      publicIPv4 = "192.168.67.22";
-      monitoringvpnIPv4 = "172.23.23.12";
-      hardware = import ./virtual-hardware.nix ({ inherit publicIPv4; });
-      stateVersion = "19.09";
-      inherit monitoringvpnKeyDir;
-      inherit sshUsers;
-    });
+    storage1 = let publicIPv4 = "192.168.67.22"; in {
+      imports = [
+        lib.storage
+        (import ./virtual-hardware.nix ({ inherit publicIPv4; }))
+        (lib.customize-storage cfg sshUsers publicIPv4 monitoringvpnKeyDir "172.23.23.12" "19.09")
+      ];
+    };
 
-    "storage2" = lib.make-testing (cfg // rec {
-      publicIPv4 = "192.168.67.23";
-      monitoringvpnIPv4 = "172.23.23.13";
-      hardware = import ./virtual-hardware.nix ({ inherit publicIPv4; });
-      stateVersion = "19.09";
-      inherit monitoringvpnKeyDir;
-      inherit sshUsers;
-    });
+    storage2 = let publicIPv4 = "192.168.67.23"; in rec {
+      imports = [
+        lib.storage
+        (import ./virtual-hardware.nix ({ inherit publicIPv4; }))
+        (lib.customize-storage cfg sshUsers publicIPv4 monitoringvpnKeyDir "172.23.23.13" "19.09")
+      ];
+    };
 
     "monitoring" = lib.make-monitoring (cfg // rec {
       publicIPv4 = "192.168.67.24";
diff --git a/morph/grid/production/grid.nix b/morph/grid/production/grid.nix
index 8cdeafe8..106f6729 100644
--- a/morph/grid/production/grid.nix
+++ b/morph/grid/production/grid.nix
@@ -59,46 +59,65 @@ in lib.make-grid {
       ];
     };
 
-    "storage001" = lib.make-storage (cfg // {
-        cfg = import ./storage001-config.nix;
-        inherit sshUsers;
-        hardware = ./storage001-hardware.nix;
-        stateVersion = "19.09";
-        monitoringvpnIPv4 = "172.23.23.21";
-        inherit monitoringvpnKeyDir;
-    });
-    "storage002" = lib.make-storage (cfg // {
-        cfg = import ./storage002-config.nix;
-        inherit sshUsers;
-        hardware = ./storage002-hardware.nix;
-        stateVersion = "19.09";
-        monitoringvpnIPv4 = "172.23.23.22";
-        inherit monitoringvpnKeyDir;
-    });
-    "storage003" = lib.make-storage (cfg // {
-        cfg = import ./storage003-config.nix;
-        inherit sshUsers;
-        hardware = ./storage003-hardware.nix;
-        stateVersion = "19.09";
-        monitoringvpnIPv4 = "172.23.23.23";
-        inherit monitoringvpnKeyDir;
-    });
-    "storage004" = lib.make-storage (cfg // {
-        cfg = import ./storage004-config.nix;
-        inherit sshUsers;
-        hardware = ./storage004-hardware.nix;
-        stateVersion = "19.09";
-        monitoringvpnIPv4 = "172.23.23.24";
-        inherit monitoringvpnKeyDir;
-    });
-    "storage005" = lib.make-storage (cfg // {
-        cfg = import ./storage005-config.nix;
-        inherit sshUsers;
-        hardware = ./storage005-hardware.nix;
-        stateVersion = "19.03";
-        monitoringvpnIPv4 = "172.23.23.25";
-        inherit monitoringvpnKeyDir;
-    });
+    "storage001" = let nodecfg = import ./storage001-config.nix; in {
+      imports = [
+        ./storage001-hardware.nix
+        # Slightly awkwardly, enable some of our hardware / network / bootloader options.
+        ../../../nixos/modules/100tb.nix
+        lib.storage
+        (lib.customize-storage cfg sshUsers nodecfg.publicIPv4 monitoringvpnKeyDir "172.23.23.21" "19.09")
+      ];
+      # And supply configuration for those hardware / network / bootloader options.
+      "100tb".config = nodecfg;
+    };
+
+    "storage002" = let nodecfg = import ./storage002-config.nix; in {
+      imports = [
+        ./storage002-hardware.nix
+        # Slightly awkwardly, enable some of our hardware / network / bootloader options.
+        ../../../nixos/modules/100tb.nix
+        lib.storage
+        (lib.customize-storage cfg sshUsers nodecfg.publicIPv4 monitoringvpnKeyDir "172.23.23.22" "19.09")
+      ];
+      # And supply configuration for those hardware / network / bootloader options.
+      "100tb".config = nodecfg;
+    };
+
+    "storage003" = let nodecfg = import ./storage003-config.nix; in {
+      imports = [
+        ./storage003-hardware.nix
+        # Slightly awkwardly, enable some of our hardware / network / bootloader options.
+        ../../../nixos/modules/100tb.nix
+        lib.storage
+        (lib.customize-storage cfg sshUsers nodecfg.publicIPv4 monitoringvpnKeyDir "172.23.23.23" "19.09")
+      ];
+      # And supply configuration for those hardware / network / bootloader options.
+      "100tb".config = nodecfg;
+    };
+
+    "storage004" = let nodecfg = import ./storage004-config.nix; in {
+      imports = [
+        ./storage004-hardware.nix
+        # Slightly awkwardly, enable some of our hardware / network / bootloader options.
+        ../../../nixos/modules/100tb.nix
+        lib.storage
+        (lib.customize-storage cfg sshUsers nodecfg.publicIPv4 monitoringvpnKeyDir "172.23.23.24" "19.09")
+      ];
+      # And supply configuration for those hardware / network / bootloader options.
+      "100tb".config = nodecfg;
+    };
+
+    "storage005" = let nodecfg = import ./storage005-config.nix; in {
+      imports = [
+        ./storage005-hardware.nix
+        # Slightly awkwardly, enable some of our hardware / network / bootloader options.
+        ../../../nixos/modules/100tb.nix
+        lib.storage
+        (lib.customize-storage cfg sshUsers nodecfg.publicIPv4 monitoringvpnKeyDir "172.23.23.25" "19.03")
+      ];
+      # And supply configuration for those hardware / network / bootloader options.
+      "100tb".config = nodecfg;
+    };
 
     "monitoring" = lib.make-monitoring (cfg // {
       publicIPv4 = "monitoring.private.storage";
diff --git a/morph/grid/testing/grid.nix b/morph/grid/testing/grid.nix
index e7d68256..0004a469 100644
--- a/morph/grid/testing/grid.nix
+++ b/morph/grid/testing/grid.nix
@@ -28,14 +28,13 @@ in lib.make-grid {
       ];
     };
 
-    "storage001" = lib.make-testing (cfg // {
-      publicIPv4 = "3.120.26.190";
-      monitoringvpnIPv4 = "172.23.23.12";
-      inherit monitoringvpnKeyDir;
-      inherit sshUsers;
-      hardware = ./testing001-hardware.nix;
-      stateVersion = "19.03";
-    });
+    storage001 = let publicIPv4 = "3.120.26.190"; in {
+      imports = [
+        lib.storage
+        ./testing001-hardware.nix
+        (lib.customize-storage cfg sshUsers publicIPv4 monitoringvpnKeyDir "172.23.23.12" "19.03")
+      ];
+    };
 
     "monitoring" = lib.make-monitoring (cfg // {
       publicIPv4 = "18.156.171.217";
diff --git a/morph/lib/customize-storage.nix b/morph/lib/customize-storage.nix
new file mode 100644
index 00000000..0f5ae16f
--- /dev/null
+++ b/morph/lib/customize-storage.nix
@@ -0,0 +1,23 @@
+cfg: sshUsers: publicIPv4: monitoringvpnKeyDir: monitoringvpnIPv4: stateVersion: {
+  deployment.secrets = {
+    "ristretto-signing-key".source = cfg.ristrettoSigningKeyPath;
+    "monitoringvpn-secret-key".source = "${monitoringvpnKeyDir}/${monitoringvpnIPv4}.key";
+    "monitoringvpn-preshared-key".source = "${monitoringvpnKeyDir}/preshared.key";
+  };
+
+  services.private-storage = {
+    sshUsers = sshUsers;
+    inherit publicIPv4;
+    inherit (cfg) passValue;
+    inherit (cfg) publicStoragePort;
+  };
+
+  services.private-storage.monitoring.vpn.client = {
+    enable = true;
+    ip = monitoringvpnIPv4;
+    endpoint = cfg.monitoringvpnEndpoint;
+    endpointPublicKeyFile = "${monitoringvpnKeyDir}/server.pub";
+  };
+
+  system.stateVersion = stateVersion;
+}
diff --git a/morph/lib/default.nix b/morph/lib/default.nix
index 30ef2239..97973b84 100644
--- a/morph/lib/default.nix
+++ b/morph/lib/default.nix
@@ -1,11 +1,12 @@
 rec {
   make-grid = import ./make-grid.nix;
-  make-testing = import ./make-testing.nix;
-  make-storage = import ./make-storage.nix;
   make-monitoring = import ./make-monitoring.nix;
 
   hardware-aws = import ./issuer-aws.nix;
 
   issuer = import ./issuer.nix;
   customize-issuer = import ./customize-issuer.nix;
+
+  storage = import ./storage.nix;
+  customize-storage = import ./customize-storage.nix;
 }
diff --git a/morph/lib/make-storage.nix b/morph/lib/make-storage.nix
deleted file mode 100644
index 6619336d..00000000
--- a/morph/lib/make-storage.nix
+++ /dev/null
@@ -1,109 +0,0 @@
-# Define the function that defines the node.
-{ cfg                        # Get the configuration that's specific to this node.
-, hardware                   # The path to the hardware configuration for this node.
-, publicStoragePort          # The storage port number on which to accept connections.
-, ristrettoSigningKeyPath    # The *local* path to the Ristretto signing key file.
-, passValue                  # Bytes component of size×time value of passes.
-, sshUsers                   # Users for which to configure SSH access to this node.
-, stateVersion               # The value for system.stateVersion on this node.
-                             # This value determines the NixOS release with
-                             # which your system is to be compatible, in order
-                             # to avoid breaking some software such as
-                             # database servers. You should change this only
-                             # after NixOS release notes say you should.
-, monitoringvpnKeyDir ? null # The directory that holds the VPN keys.
-, monitoringvpnIPv4 ? null   # This node's IP in the monitoring VPN.
-, monitoringvpnEndpoint ? null # The VPN server and port.
-, ...
-}: let
-
-  enableVpn = monitoringvpnKeyDir != null &&
-              monitoringvpnIPv4 != null &&
-              monitoringvpnEndpoint != null;
-
-  vpnSecrets = if !enableVpn then {} else {
-    "monitoringvpn-secret-key" = {
-      source = monitoringvpnKeyDir + "/${monitoringvpnIPv4}.key";
-      destination = "/run/keys/monitoringvpn/client.key";
-      owner.user = "root";
-      owner.group = "root";
-      permissions = "0400";
-      action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
-    };
-    "monitoringvpn-preshared-key" = {
-      source = monitoringvpnKeyDir + "/preshared.key";
-      destination = "/run/keys/monitoringvpn/preshared.key";
-      owner.user = "root";
-      owner.group = "root";
-      permissions = "0400";
-      action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
-    };
-  };
-
-in rec {
-  deployment = {
-    targetHost = cfg.publicIPv4;
-
-    secrets = {
-      "ristretto-signing-key" = {
-        source = ristrettoSigningKeyPath;
-        destination = "/run/keys/ristretto.signing-key";
-        owner.user = "root";
-        owner.group = "root";
-        permissions = "0400";
-        # Service name here matches the name defined by our tahoe-lafs nixos
-        # module.  It would be nice to not have to hard-code it here.  Can we
-        # extract it from the tahoe-lafs nixos module somehow?
-        action = ["sudo" "systemctl" "restart" "tahoe.storage.service"];
-      };
-    } // vpnSecrets;
-  };
-
-  # Any extra NixOS modules to load on this server.
-  imports = [
-    # Include the results of the hardware scan.
-    hardware
-    # Configure it as a system operated by 100TB.
-    ../../nixos/modules/100tb.nix
-    # Bring in our module for configuring the Tahoe-LAFS service and other
-    # Private Storage-specific things.
-    ../../nixos/modules/private-storage.nix
-    # Connect to the monitoringvpn.
-    ../../nixos/modules/monitoring/vpn/client.nix
-    # Expose base system metrics over the monitoringvpn.
-    ../../nixos/modules/monitoring/exporters/node.nix
-  ];
-
-  # Pass the configuration specific to this host to the 100TB module to be
-  # expanded into a complete system configuration.  See the 100tb module for
-  # handling of this value.
-  #
-  # The module name is quoted because `1` makes `100tb` look an awful lot like
-  # it should be a number.
-  "100tb".config = cfg;
-
-  # Turn on the Private Storage (Tahoe-LAFS) service.
-  services.private-storage = {
-    # Yep.  Turn it on.
-    enable = true;
-    # Get the public IPv4 address from the node configuration.
-    inherit (cfg) publicIPv4;
-    # And the port to operate on is specified via parameter.
-    inherit publicStoragePort;
-    # Give it the Ristretto signing key, too, to support authorization.
-    ristrettoSigningKeyPath = deployment.secrets.ristretto-signing-key.destination;
-    # Assign the configured pass value.
-    inherit passValue;
-    # It gets the users, too.
-    inherit sshUsers;
-  };
-
-  system.stateVersion = stateVersion;
-
-  services.private-storage.monitoring.vpn.client = if !enableVpn then {} else {
-    enable = true;
-    ip = monitoringvpnIPv4;
-    endpoint = monitoringvpnEndpoint;
-    endpointPublicKeyFile = monitoringvpnKeyDir + "/server.pub";
-  };
-}
diff --git a/morph/lib/make-testing.nix b/morph/lib/make-testing.nix
deleted file mode 100644
index 3f6e767d..00000000
--- a/morph/lib/make-testing.nix
+++ /dev/null
@@ -1,80 +0,0 @@
-{ publicIPv4
-, hardware
-, publicStoragePort
-, ristrettoSigningKeyPath
-, passValue
-, sshUsers
-, stateVersion
-, monitoringvpnKeyDir ? null
-, monitoringvpnIPv4 ? null
-, monitoringvpnEndpoint ? null
-, ... }: let
-
-  enableVpn = monitoringvpnKeyDir != null &&
-              monitoringvpnIPv4 != null &&
-              monitoringvpnEndpoint != null;
-
-  vpnSecrets = if !enableVpn then {} else {
-    "monitoringvpn-secret-key" = {
-      source = monitoringvpnKeyDir + "/${monitoringvpnIPv4}.key";
-      destination = "/run/keys/monitoringvpn/client.key";
-      owner.user = "root";
-      owner.group = "root";
-      permissions = "0400";
-      action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
-    };
-    "monitoringvpn-preshared-key" = {
-      source = monitoringvpnKeyDir + "/preshared.key";
-      destination = "/run/keys/monitoringvpn/preshared.key";
-      owner.user = "root";
-      owner.group = "root";
-      permissions = "0400";
-      action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
-    };
-  };
-
-in rec {
-
-  deployment = {
-    targetHost = publicIPv4;
-
-    secrets = {
-      "ristretto-signing-key" = {
-        source = ristrettoSigningKeyPath;
-        destination = "/run/keys/ristretto.signing-key";
-        owner.user = "root";
-        owner.group = "root";
-        permissions = "0400";
-        # Service name here matches the name defined by our tahoe-lafs nixos
-        # module.  It would be nice to not have to hard-code it here.  Can we
-        # extract it from the tahoe-lafs nixos module somehow?
-        action = ["sudo" "systemctl" "restart" "tahoe.storage.service"];
-      };
-    } // vpnSecrets;
-  };
-
-  imports = [
-    hardware
-    ../../nixos/modules/private-storage.nix
-    ../../nixos/modules/monitoring/vpn/client.nix
-    ../../nixos/modules/monitoring/exporters/node.nix
-  ];
-
-  services.private-storage =
-  { enable = true;
-    inherit publicIPv4;
-    inherit publicStoragePort;
-    ristrettoSigningKeyPath = deployment.secrets.ristretto-signing-key.destination;
-    inherit passValue;
-    inherit sshUsers;
-  };
-
-  system.stateVersion = stateVersion;
-
-  services.private-storage.monitoring.vpn.client = if !enableVpn then {} else {
-    enable = true;
-    ip = monitoringvpnIPv4;
-    endpoint = monitoringvpnEndpoint;
-    endpointPublicKeyFile = monitoringvpnKeyDir + "/server.pub";
-  };
-}
diff --git a/morph/lib/storage.nix b/morph/lib/storage.nix
new file mode 100644
index 00000000..768125ae
--- /dev/null
+++ b/morph/lib/storage.nix
@@ -0,0 +1,78 @@
+{ config, ... }:
+rec {
+  deployment = {
+    secrets = {
+      "ristretto-signing-key" = {
+        # source = ...;
+        destination = "/run/keys/ristretto.signing-key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        # Service name here matches the name defined by our tahoe-lafs nixos
+        # module.  It would be nice to not have to hard-code it here.  Can we
+        # extract it from the tahoe-lafs nixos module somehow?
+        action = ["sudo" "systemctl" "restart" "tahoe.storage.service"];
+      };
+      "monitoringvpn-secret-key" = {
+        # source = ...;
+        destination = "/run/keys/monitoringvpn/client.key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
+      };
+      "monitoringvpn-preshared-key" = {
+        # source = ...;
+        destination = "/run/keys/monitoringvpn/preshared.key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
+      };
+    };
+  };
+
+  # Any extra NixOS modules to load on this server.
+  imports = [
+    # Bring in our module for configuring the Tahoe-LAFS service and other
+    # Private Storage-specific things.
+    ../../nixos/modules/private-storage.nix
+    # Connect to the monitoringvpn.
+    ../../nixos/modules/monitoring/vpn/client.nix
+    # Expose base system metrics over the monitoringvpn.
+    ../../nixos/modules/monitoring/exporters/node.nix
+  ];
+
+  # Pass the configuration specific to this host to the 100TB module to be
+  # expanded into a complete system configuration.  See the 100tb module for
+  # handling of this value.
+  #
+  # The module name is quoted because `1` makes `100tb` look an awful lot like
+  # it should be a number.
+  # "100tb".config = cfg;
+
+  # Turn on the Private Storage (Tahoe-LAFS) service.
+  services.private-storage = {
+    # Yep.  Turn it on.
+    enable = true;
+    # Get the public IPv4 address from the node configuration.
+    # inherit (cfg) publicIPv4;
+    # And the port to operate on is specified via parameter.
+    # inherit publicStoragePort;
+    # Give it the Ristretto signing key, too, to support authorization.
+    ristrettoSigningKeyPath = deployment.secrets.ristretto-signing-key.destination;
+    # Assign the configured pass value.
+    # inherit passValue;
+    # It gets the users, too.
+    # sshUsers = ...;
+  };
+
+  # system.stateVersion = ...'
+
+  services.private-storage.monitoring.vpn.client = {
+    # enable = ...;
+    # ip = ...;
+    # endpoint = ...;
+    # endpointPublicKeyFile = ...;
+  };
+}
-- 
GitLab