summary refs log tree commit diff
path: root/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix')
-rw-r--r--nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix162
1 files changed, 162 insertions, 0 deletions
diff --git a/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix b/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
new file mode 100644
index 00000000000..dfdfc50d8ae
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
@@ -0,0 +1,162 @@
+# In the following context a parameter is an attribute set that
+# contains a NixOS option and a render function. It also contains the
+# attribute: '_type = "param"' so we can distinguish it from other
+# sets.
+#
+# The render function is used to convert the value of the option to a
+# snippet of strongswan.conf. Most parameters simply render their
+# value to a string. For example, take the following parameter:
+#
+#   threads = mkIntParam 10 "Threads to use for request handling.";
+#
+# When a users defines the corresponding option as for example:
+#
+#   services.strongswan-swanctl.strongswan.threads = 32;
+#
+# It will get rendered to the following snippet in strongswan.conf:
+#
+#   threads = 32
+#
+# Some parameters however need to be able to change the attribute
+# name. For example, take the following parameter:
+#
+#   id = mkPrefixedAttrsOfParam (mkOptionalStrParam "") "...";
+#
+# A user can define the corresponding option as for example:
+#
+#   id = {
+#     "foo" = "bar";
+#     "baz" = "qux";
+#   };
+#
+# This will get rendered to the following snippet:
+#
+#   foo-id = bar
+#   baz-id = qux
+#
+# For this reason the render function is not simply a function from
+# value -> string but a function from a value to an attribute set:
+# { "${name}" = string }. This allows parameters to change the attribute
+# name like in the previous example.
+
+lib :
+
+with lib;
+with (import ./param-lib.nix lib);
+
+rec {
+  mkParamOfType = type : strongswanDefault : description : {
+    _type = "param";
+    option = mkOption {
+      type = types.nullOr type;
+      default = null;
+      description = documentDefault description strongswanDefault;
+    };
+    render = single toString;
+  };
+
+  documentDefault = description : strongswanDefault :
+    if strongswanDefault == null
+    then description
+    else description + ''
+      </para><para>
+      StrongSwan default: <literal><![CDATA[${builtins.toJSON strongswanDefault}]]></literal>
+    '';
+
+  single = f: name: value: { ${name} = f value; };
+
+  mkStrParam         = mkParamOfType types.str;
+  mkOptionalStrParam = mkStrParam null;
+
+  mkEnumParam = values : mkParamOfType (types.enum values);
+
+  mkIntParam         = mkParamOfType types.int;
+  mkOptionalIntParam = mkIntParam null;
+
+  # We should have floats in Nix...
+  mkFloatParam = mkStrParam;
+
+  # TODO: Check for hex format:
+  mkHexParam         = mkStrParam;
+  mkOptionalHexParam = mkOptionalStrParam;
+
+  # TODO: Check for duration format:
+  mkDurationParam         = mkStrParam;
+  mkOptionalDurationParam = mkOptionalStrParam;
+
+  mkYesNoParam = strongswanDefault : description : {
+    _type = "param";
+    option = mkOption {
+      type = types.nullOr types.bool;
+      default = null;
+      description = documentDefault description strongswanDefault;
+    };
+    render = single (b: if b then "yes" else "no");
+  };
+  yes = true;
+  no  = false;
+
+  mkSpaceSepListParam = mkSepListParam " ";
+  mkCommaSepListParam = mkSepListParam ",";
+
+  mkSepListParam = sep : strongswanDefault : description : {
+    _type = "param";
+    option = mkOption {
+      type = types.nullOr (types.listOf types.str);
+      default = null;
+      description = documentDefault description strongswanDefault;
+    };
+    render = single (value: concatStringsSep sep value);
+  };
+
+  mkAttrsOfParams = params :
+    mkAttrsOf params (types.submodule {options = paramsToOptions params;});
+
+  mkAttrsOfParam = param :
+    mkAttrsOf param param.option.type;
+
+  mkAttrsOf = param : option : description : {
+    _type = "param";
+    option = mkOption {
+      type = types.attrsOf option;
+      default = {};
+      inherit description;
+    };
+    render = single (attrs:
+      (paramsToRenderedStrings attrs
+        (mapAttrs (_n: _v: param) attrs)));
+  };
+
+  mkPrefixedAttrsOfParams = params :
+    mkPrefixedAttrsOf params (types.submodule {options = paramsToOptions params;});
+
+  mkPrefixedAttrsOfParam = param :
+    mkPrefixedAttrsOf param param.option.type;
+
+  mkPrefixedAttrsOf = p : option : description : {
+    _type = "param";
+    option = mkOption {
+      type = types.attrsOf option;
+      default = {};
+      inherit description;
+    };
+    render = prefix: attrs:
+      let prefixedAttrs = mapAttrs' (name: nameValuePair "${prefix}-${name}") attrs;
+      in paramsToRenderedStrings prefixedAttrs
+           (mapAttrs (_n: _v: p) prefixedAttrs);
+  };
+
+  mkPostfixedAttrsOfParams = params : description : {
+    _type = "param";
+    option = mkOption {
+      type = types.attrsOf (types.submodule {options = paramsToOptions params;});
+      default = {};
+      inherit description;
+    };
+    render = postfix: attrs:
+      let postfixedAttrs = mapAttrs' (name: nameValuePair "${name}-${postfix}") attrs;
+      in paramsToRenderedStrings postfixedAttrs
+           (mapAttrs (_n: _v: params) postfixedAttrs);
+  };
+
+}