11 cfg = config.services.webhook;
12 defaultUser = "webhook";
14 hookFormat = pkgs.formats.json { };
16 hookType = types.submodule (
19 freeformType = hookFormat.type;
25 The ID of your hook. This value is used to create the HTTP endpoint (`protocol://yourserver:port/prefix/''${id}`).
28 execute-command = mkOption {
30 description = "The command that should be executed when the hook is triggered.";
37 mapAttrsToList (name: hook: hookFormat.generate "webhook-${name}.json" [ hook ]) cfg.hooks
39 name: hook: pkgs.writeText "webhook-${name}.json.tmpl" "[${hook}]"
46 enable = mkEnableOption ''
47 [Webhook](https://github.com/adnanh/webhook), a server written in Go that allows you to create HTTP endpoints (hooks),
48 which execute configured commands for any person or service that knows the URL
51 package = mkPackageOption pkgs "webhook" { };
54 default = defaultUser;
56 Webhook will be run under this user.
58 If set, you must create this user yourself!
63 default = defaultUser;
65 Webhook will be run under this group.
67 If set, you must create this group yourself!
74 The IP webhook should serve hooks on.
76 The default means it can be reached on any interface if `openFirewall = true`.
82 description = "The port webhook should be reachable from.";
84 openFirewall = mkOption {
88 Open the configured port in the firewall for external ingress traffic.
89 Preferably the Webhook server is instead put behind a reverse proxy.
92 enableTemplates = mkOption {
94 default = cfg.hooksTemplated != { };
95 defaultText = literalExpression "hooksTemplated != {}";
97 Enable the generated hooks file to be parsed as a Go template.
98 See [the documentation](https://github.com/adnanh/webhook/blob/master/docs/Templates.md) for more information.
101 urlPrefix = mkOption {
105 The URL path prefix to use for served hooks (`protocol://yourserver:port/''${prefix}/hook-id`).
109 type = types.attrsOf hookType;
113 execute-command = "echo";
114 response-message = "Webhook is reachable!";
117 execute-command = "/var/scripts/redeploy.sh";
118 command-working-directory = "/var/webhook";
122 The actual configuration of which hooks will be served.
124 Read more on the [project homepage] and on the [hook definition] page.
125 At least one hook needs to be configured.
127 [hook definition]: https://github.com/adnanh/webhook/blob/master/docs/Hook-Definition.md
128 [project homepage]: https://github.com/adnanh/webhook#configuration
131 hooksTemplated = mkOption {
132 type = types.attrsOf types.str;
137 "id": "echo-template",
138 "execute-command": "echo",
139 "response-message": "{{ getenv "MESSAGE" }}"
144 Same as {option}`hooks`, but these hooks are specified as literal strings instead of Nix values,
145 and hence can include [template syntax](https://github.com/adnanh/webhook/blob/master/docs/Templates.md)
146 which might not be representable as JSON.
148 Template syntax requires the {option}`enableTemplates` option to be set to `true`, which is
149 done by default if this option is set.
155 description = "Whether to show verbose output.";
157 extraArgs = mkOption {
158 type = types.listOf types.str;
160 example = [ "-secure" ];
162 These are arguments passed to the webhook command in the systemd service.
163 You can find the available arguments and options in the [documentation][parameters].
165 [parameters]: https://github.com/adnanh/webhook/blob/master/docs/Webhook-Parameters.md
168 environment = mkOption {
169 type = types.attrsOf types.str;
171 description = "Extra environment variables passed to webhook.";
176 config = mkIf cfg.enable {
179 overlappingHooks = builtins.intersectAttrs cfg.hooks cfg.hooksTemplated;
183 assertion = hookFiles != [ ];
184 message = "At least one hook needs to be configured for webhook to run.";
187 assertion = overlappingHooks == { };
188 message = "`services.webhook.hooks` and `services.webhook.hooksTemplated` have overlapping attribute(s): ${concatStringsSep ", " (builtins.attrNames overlappingHooks)}";
192 users.users = mkIf (cfg.user == defaultUser) {
196 description = "Webhook daemon user";
200 users.groups = mkIf (cfg.user == defaultUser && cfg.group == defaultUser) {
201 ${defaultUser} = { };
204 networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
206 systemd.services.webhook = {
207 description = "Webhook service";
208 after = [ "network.target" ];
209 wantedBy = [ "multi-user.target" ];
210 environment = config.networking.proxy.envVars // cfg.environment;
222 ++ concatMap (hook: [
226 ++ optional cfg.enableTemplates "-template"
227 ++ optional cfg.verbose "-verbose"
231 ${cfg.package}/bin/webhook ${escapeShellArgs args}
234 Restart = "on-failure";