Merge pull request #39671 from johanot/keepalived-vrrpInstanceTracking

nixos/keepalived: Implemented vrrp-instance track scripts and track interfaces
This commit is contained in:
Sarah Brofeldt 2018-05-09 20:54:36 +02:00 committed by GitHub
commit 3befef8279
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 2 deletions

View file

@ -8,10 +8,12 @@ let
keepalivedConf = pkgs.writeText "keepalived.conf" ''
global_defs {
${optionalString cfg.enableScriptSecurity "enable_script_security"}
${snmpGlobalDefs}
${cfg.extraGlobalDefs}
}
${vrrpScriptStr}
${vrrpInstancesStr}
${cfg.extraConfig}
'';
@ -26,6 +28,22 @@ let
+ optionalString enableTraps "enable_traps"
);
vrrpScriptStr = concatStringsSep "\n" (map (s:
''
vrrp_script ${s.name} {
script "${s.script}"
interval ${toString s.interval}
fall ${toString s.fall}
rise ${toString s.rise}
timeout ${toString s.timeout}
weight ${toString s.weight}
user ${s.user} ${optionalString (s.group != null) s.group}
${s.extraConfig}
}
''
) vrrpScripts);
vrrpInstancesStr = concatStringsSep "\n" (map (i:
''
vrrp_instance ${i.name} {
@ -49,6 +67,18 @@ let
${concatMapStringsSep "\n" virtualIpLine i.virtualIps}
}
${optionalString (builtins.length i.trackScripts > 0) ''
track_script {
${concatStringsSep "\n" i.trackScripts}
}
''}
${optionalString (builtins.length i.trackInterfaces > 0) ''
track_interface {
${concatStringsSep "\n" i.trackInterfaces}
}
''}
${i.extraConfig}
}
''
@ -64,6 +94,12 @@ let
notNullOrEmpty = s: !(s == null || s == "");
vrrpScripts = mapAttrsToList (name: config:
{
inherit name;
} // config
) cfg.vrrpScripts;
vrrpInstances = mapAttrsToList (iName: iConfig:
{
name = iName;
@ -86,7 +122,8 @@ let
{ assertion = !i.vmacXmitBase || i.useVmac;
message = "services.keepalived.vrrpInstances.${i.name}.vmacXmitBase has no effect when services.keepalived.vrrpInstances.${i.name}.useVmac is not set.";
}
] ++ flatten (map (virtualIpAssertions i.name) i.virtualIps);
] ++ flatten (map (virtualIpAssertions i.name) i.virtualIps)
++ flatten (map (vrrpScriptAssertion i.name) i.trackScripts);
virtualIpAssertions = vrrpName: ip: [
{ assertion = ip.addr != "";
@ -94,6 +131,11 @@ let
}
];
vrrpScriptAssertion = vrrpName: scriptName: {
assertion = builtins.hasAttr scriptName cfg.vrrpScripts;
message = "services.keepalived.vrrpInstances.${vrrpName} trackscript ${scriptName} is not defined in services.keepalived.vrrpScripts.";
};
pidFile = "/run/keepalived.pid";
in
@ -110,6 +152,14 @@ in
'';
};
enableScriptSecurity = mkOption {
type = types.bool;
default = false;
description = ''
Don't run scripts configured to be run as root if any part of the path is writable by a non-root user.
'';
};
snmp = {
enable = mkOption {
@ -181,8 +231,16 @@ in
};
vrrpScripts = mkOption {
type = types.attrsOf (types.submodule (import ./vrrp-script-options.nix {
inherit lib;
}));
default = {};
description = "Declarative vrrp script config";
};
vrrpInstances = mkOption {
type = types.attrsOf (types.submodule (import ./vrrp-options.nix {
type = types.attrsOf (types.submodule (import ./vrrp-instance-options.nix {
inherit lib;
}));
default = {};

View file

@ -108,6 +108,20 @@ with lib;
description = "Declarative vhost config";
};
trackScripts = mkOption {
type = types.listOf types.str;
default = [];
example = [ "chk_cmd1" "chk_cmd2" ];
description = "List of script names to invoke for health tracking.";
};
trackInterfaces = mkOption {
type = types.listOf types.str;
default = [];
example = [ "eth0" "eth1" ];
description = "List of network interfaces to monitor for health tracking.";
};
extraConfig = mkOption {
type = types.lines;
default = "";

View file

@ -0,0 +1,64 @@
{ lib } :
with lib;
with lib.types;
{
options = {
script = mkOption {
type = str;
example = "\${pkgs.curl} -f http://localhost:80";
description = "(Path of) Script command to execute followed by args, i.e. cmd [args]...";
};
interval = mkOption {
type = int;
default = 1;
description = "Seconds between script invocations.";
};
timeout = mkOption {
type = int;
default = 5;
description = "Seconds after which script is considered to have failed.";
};
weight = mkOption {
type = int;
default = 0;
description = "Following a failure, adjust the priority by this weight.";
};
rise = mkOption {
type = int;
default = 5;
description = "Required number of successes for OK transition.";
};
fall = mkOption {
type = int;
default = 3;
description = "Required number of failures for KO transition.";
};
user = mkOption {
type = str;
default = "keepalived_script";
description = "Name of user to run the script under.";
};
group = mkOption {
type = nullOr str;
default = null;
description = "Name of group to run the script under. Defaults to user group.";
};
extraConfig = mkOption {
type = lines;
default = "";
description = "Extra lines to be added verbatim to the vrrp_script section.";
};
};
}