97 lines
2.8 KiB
Nix
97 lines
2.8 KiB
Nix
|
{ pkgs, lib, ... }:
|
||
|
|
||
|
# Based on
|
||
|
# - https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html
|
||
|
# - https://manpages.debian.org/unstable/heimdal-docs/krb5.conf.5heimdal.en.html
|
||
|
|
||
|
let
|
||
|
inherit (lib) boolToString concatMapStringsSep concatStringsSep filter
|
||
|
isAttrs isBool isList mapAttrsToList mdDoc mkOption singleton splitString;
|
||
|
inherit (lib.types) attrsOf bool coercedTo either int listOf oneOf path
|
||
|
str submodule;
|
||
|
in
|
||
|
{ }: rec {
|
||
|
sectionType = let
|
||
|
relation = oneOf [
|
||
|
(listOf (attrsOf value))
|
||
|
(attrsOf value)
|
||
|
value
|
||
|
];
|
||
|
value = either (listOf atom) atom;
|
||
|
atom = oneOf [int str bool];
|
||
|
in attrsOf relation;
|
||
|
|
||
|
type = submodule {
|
||
|
freeformType = attrsOf sectionType;
|
||
|
options = {
|
||
|
include = mkOption {
|
||
|
default = [ ];
|
||
|
description = mdDoc ''
|
||
|
Files to include in the Kerberos configuration.
|
||
|
'';
|
||
|
type = coercedTo path singleton (listOf path);
|
||
|
};
|
||
|
includedir = mkOption {
|
||
|
default = [ ];
|
||
|
description = mdDoc ''
|
||
|
Directories containing files to include in the Kerberos configuration.
|
||
|
'';
|
||
|
type = coercedTo path singleton (listOf path);
|
||
|
};
|
||
|
module = mkOption {
|
||
|
default = [ ];
|
||
|
description = mdDoc ''
|
||
|
Modules to obtain Kerberos configuration from.
|
||
|
'';
|
||
|
type = coercedTo path singleton (listOf path);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
generate = let
|
||
|
indent = str: concatMapStringsSep "\n" (line: " " + line) (splitString "\n" str);
|
||
|
|
||
|
formatToplevel = args @ {
|
||
|
include ? [ ],
|
||
|
includedir ? [ ],
|
||
|
module ? [ ],
|
||
|
...
|
||
|
}: let
|
||
|
sections = removeAttrs args [ "include" "includedir" "module" ];
|
||
|
in concatStringsSep "\n" (filter (x: x != "") [
|
||
|
(concatStringsSep "\n" (mapAttrsToList formatSection sections))
|
||
|
(concatMapStringsSep "\n" (m: "module ${m}") module)
|
||
|
(concatMapStringsSep "\n" (i: "include ${i}") include)
|
||
|
(concatMapStringsSep "\n" (i: "includedir ${i}") includedir)
|
||
|
]);
|
||
|
|
||
|
formatSection = name: section: ''
|
||
|
[${name}]
|
||
|
${indent (concatStringsSep "\n" (mapAttrsToList formatRelation section))}
|
||
|
'';
|
||
|
|
||
|
formatRelation = name: relation:
|
||
|
if isAttrs relation
|
||
|
then ''
|
||
|
${name} = {
|
||
|
${indent (concatStringsSep "\n" (mapAttrsToList formatValue relation))}
|
||
|
}''
|
||
|
else if isList relation
|
||
|
then
|
||
|
concatMapStringsSep "\n" (formatRelation name) relation
|
||
|
else formatValue name relation;
|
||
|
|
||
|
formatValue = name: value:
|
||
|
if isList value
|
||
|
then concatMapStringsSep "\n" (formatAtom name) value
|
||
|
else formatAtom name value;
|
||
|
|
||
|
formatAtom = name: atom: let
|
||
|
v = if isBool atom then boolToString atom else toString atom;
|
||
|
in "${name} = ${v}";
|
||
|
in
|
||
|
name: value: pkgs.writeText name ''
|
||
|
${formatToplevel value}
|
||
|
'';
|
||
|
}
|