Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

postfix: Make config an attribute set #20218

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 84 additions & 95 deletions nixos/modules/services/mail/postfix.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,101 +25,75 @@ let

clientRestrictions = concatStringsSep ", " (clientAccess ++ dnsBl);

mainCf =
''
compatibility_level = 9999

mail_owner = ${user}
default_privs = nobody

# NixOS specific locations
data_directory = /var/lib/postfix/data
queue_directory = /var/lib/postfix/queue

# Default location of everything in package
meta_directory = ${pkgs.postfix}/etc/postfix
command_directory = ${pkgs.postfix}/bin
sample_directory = /etc/postfix
newaliases_path = ${pkgs.postfix}/bin/newaliases
mailq_path = ${pkgs.postfix}/bin/mailq
readme_directory = no
sendmail_path = ${pkgs.postfix}/bin/sendmail
daemon_directory = ${pkgs.postfix}/libexec/postfix
manpage_directory = ${pkgs.postfix}/share/man
html_directory = ${pkgs.postfix}/share/postfix/doc/html
shlib_directory = no

''
+ optionalString config.networking.enableIPv6 ''
inet_protocols = all
''
+ (if cfg.networks != null then
''
mynetworks = ${concatStringsSep ", " cfg.networks}
''
else if cfg.networksStyle != "" then
''
mynetworks_style = ${cfg.networksStyle}
''
else
"")
+ optionalString (cfg.hostname != "") ''
myhostname = ${cfg.hostname}
''
+ optionalString (cfg.domain != "") ''
mydomain = ${cfg.domain}
''
+ optionalString (cfg.origin != "") ''
myorigin = ${cfg.origin}
''
+ optionalString (cfg.destination != null) ''
mydestination = ${concatStringsSep ", " cfg.destination}
''
+ optionalString (cfg.relayDomains != null) ''
relay_domains = ${concatStringsSep ", " cfg.relayDomains}
''
+ ''
local_recipient_maps =

relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then
cfg.relayHost
else
"[" + cfg.relayHost + "]"}

mail_spool_directory = /var/spool/mail/

setgid_group = ${setgidGroup}
''
+ optionalString (cfg.sslCert != "") ''

smtp_tls_CAfile = ${cfg.sslCACert}
smtp_tls_cert_file = ${cfg.sslCert}
smtp_tls_key_file = ${cfg.sslKey}

smtp_use_tls = yes

smtpd_tls_CAfile = ${cfg.sslCACert}
smtpd_tls_cert_file = ${cfg.sslCert}
smtpd_tls_key_file = ${cfg.sslKey}

smtpd_use_tls = yes
''
+ optionalString (cfg.recipientDelimiter != "") ''
recipient_delimiter = ${cfg.recipientDelimiter}
''
+ optionalString haveAliases ''
alias_maps = hash:/etc/postfix/aliases
''
+ optionalString haveTransport ''
transport_maps = hash:/etc/postfix/transport
''
+ optionalString haveVirtual ''
virtual_alias_maps = hash:/etc/postfix/virtual
''
+ optionalString (cfg.dnsBlacklists != []) ''
smtpd_client_restrictions = ${clientRestrictions}
''
+ cfg.extraConfig;
mainCf = let
escape = lib.replaceStrings ["$"] ["$$"];
mkList = items: "\n" + lib.concatMapStringsSep "\n " escape items;
mkVal = value:
if lib.isList value then mkList value
else " " + (if value == true then "yes"
else if value == false then "no"
else toString value);
mkEntry = name: value: "${escape name} =${mkVal value}";
in lib.concatStringsSep "\n" (lib.mapAttrsToList mkEntry cfg.config) + "\n" + cfg.extraConfig;

defaultConf = {
compatibility_level = "9999";
mail_owner = user;
default_privs = "nobody";

# NixOS specific locations
data_directory = "/var/lib/postfix/data";
queue_directory = "/var/lib/postfix/queue";

# Default location of everything in package
meta_directory = "${pkgs.postfix}/etc/postfix";
command_directory = "${pkgs.postfix}/bin";
sample_directory = "/etc/postfix";
newaliases_path = "${pkgs.postfix}/bin/newaliases";
mailq_path = "${pkgs.postfix}/bin/mailq";
readme_directory = false;
sendmail_path = "${pkgs.postfix}/bin/sendmail";
daemon_directory = "${pkgs.postfix}/libexec/postfix";
manpage_directory = "${pkgs.postfix}/share/man";
html_directory = "${pkgs.postfix}/share/postfix/doc/html";
shlib_directory = false;

inet_protocols = mkIf config.networking.enableIPv6 "all";
mynetworks = mkIf (cfg.networks != null) cfg.networks;
mynetworks_style = mkIf (cfg.networksStyle != "")
cfg.networksStyle;
myhostname = mkIf (cfg.hostname != "") cfg.hostname;
mydomain = mkIf (cfg.domain != "") cfg.domain;
myorigin = mkIf (cfg.origin != "") cfg.origin;
mydestination = mkIf (cfg.destination != null) cfg.destination;
relay_domains = mkIf (cfg.relayDomains != null) cfg.relayDomains;
local_recipient_maps = "";
relayhost = if cfg.lookupMX || cfg.relayHost == ""
then cfg.relayHost
else "[${cfg.relayHost}]";
mail_spool_directory = "/var/spool/mail/";
setgid_group = setgidGroup;

recipient_delimiter = mkIf (cfg.recipientDelimiter != "")
cfg.recipientDelimiter;
alias_maps = mkIf haveAliases "hash:/etc/postfix/aliases";
transport_maps = mkIf haveTransport "hash:/etc/postfx/transport";
virtual_alias_maps = mkIf haveVirtual "hash:/etc/postfix/virtual";
smtpd_client_restrictions = mkIf (cfg.dnsBlacklists != [])
clientRestrictions;
} // (if (cfg.sslCert != "") then {
smtp_tls_CAfile = cfg.sslCACert;
smtp_tls_cert_file = cfg.sslCert;
smtp_tls_key_file = cfg.sslKey;

smtp_use_tls = true;

smtpd_tls_CAfile = cfg.sslCACert;
smtpd_tls_cert_file = cfg.sslCert;
smtpd_tls_key_file = cfg.sslKey;

smtpd_use_tls = true;
} else {});

masterCf = ''
# ==========================================================================
Expand Down Expand Up @@ -354,6 +328,18 @@ in
";
};

config = mkOption {
type = with types; attrsOf (either bool (either str (listOf str)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feel like a little wild type, types.attrs might be enough and could provide more appropriate declaration merging than either.

The approach used in the influxdb module for a similar setting, defining a configuration attribute set and update with an attrs option, might interest you as it can be a good trade-off of verbosity and complexity.
Or there is the possibility to use a submodule to enforce the type checking, but at the cost of verbosity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this option is a good way to have some advantages from both sides. If I'd use attrs, what would { test = { foo = bar; }; } be? The postfix config has flags: "yes" and "no", lists: comma seperated strings and usual strings. This type allows a good abstraction for it.

default = defaultConf;
description = ''
The main.cf configuration file as key value set.
'';
example = {
mail_owner = "postfix";
smtp_use_tls = true;
};
};

extraConfig = mkOption {
type = types.lines;
default = "";
Expand Down Expand Up @@ -546,6 +532,9 @@ in
(mkIf (cfg.dnsBlacklists != []) {
services.postfix.mapFiles."client_access" = checkClientAccessFile;
})
(mkIf (cfg.extraConfig != "") {
warnings = [ "The services.postfix.extraConfig option was deprecated. Please use services.postfix.config instead." ];
})
]);

}