* feat: add support for systemd socket activation
If webhook has been launched via systemd socket activation, simply use the systemd-provided socket rather than opening our own.
* docs: documentation for the systemd socket activation mode
* refactor: moved setuid and setgid flags into platform-specific section
The setuid and setgid flags do not work on Windows, so moved them to platform_unix so they are only added to the flag set on compatible platforms.
Also disallow the use of setuid and setgid in combination with -socket, since a setuid webhook process would not be able to clean up a socket that was created while running as root. If you _need_ to have the socket owned by root but the webhook process running as a normal user, you can achieve the same effect with systemd socket activation.
* feat: add ability to listen on unix socket/named pipe
Add a -socket option that configures the server to listen on a Unix-domain socket or Windows named pipe instead of a TCP port. This allows webhook to be used behind a reverse proxy on multi-tenant shared hosting without the need to choose (and the permission to bind to) a free port number.
On Windows, -socket is expected to be a named pipe such as \\.\pipe\webhook, and the code uses https://github.com/microsoft/go-winio to bind the listening socket. On other platforms, -socket is the path to a Unix domain socket such as /tmp/webhook.sock, or an abstract socket name starting with @, bound using the regular net.Listen function with the "network" parameter set to "unix".
Note: this pushes our minimum Go version up to 1.21 as that is what go-winio requires, but that is already the minimum version against which we are testing in the CI matrix.
* tests: add test for the -socket option
Refactored webhook_test so that the test HTTP requests are made using an explicitly-provided http.Client, so we can run at least one test with the server bound to a socket instead of a port number, using an http.Client whose transport has been configured with a suitable Unix-domain or Windows named pipe dialer function.
* tests: use GOROOT to find go command
This should ensure that, even if a developer or CI server has multiple versions of go installed, the version used to build the tools under test will be the same version that is running the test harness.
* fix: clean up Unix socket file before exit
If webhook is restarted with the same settings but the socket file has not been deleted, webhook will be unable to bind and will exit with an error.
* docs: add -socket option to documentation
* docs: add a note about reverse proxies
- README mentions the idea of using webhook behind a reverse proxy, including with the -socket flag
- added a note in Hook-Rules that the ip-whitelist rule type does not work as expected behind a reverse proxy, and you should configure IP restrictions at the proxy level instead
When matching variables in routes, gorilla/mux uses a default pattern of
"[^/]+", thereby prohibiting slashes in variable matching. Override the
default pattern to remove this restriction.
See https://github.com/gorilla/mux/blob/v1.8.0/regexp.go#L50Fixes#421
To avoid having to pass around so many parameters to the hook package,
create a Request object to store all request-specific data. Update APIs
accordingly.
The error returned by exec.LookPath was never surfaced to the user.
Without that detail, the user can't tell the difference between a
non-existent path and a permissions issue.
Additionally, when ExecuteCommand is an absolute path, we were still
attempting to prepend the CommandWorkingDirectory if the ExecuteCommand
was not found, which made it difficult to know which path the user
intended to execute.
This commit simplifies the logic to avoid multiple attempts with
ExecuteCommand is an absolute path and changes the error message from:
error locating command: '/path/to/file'
to:
error in exec: "/path/to/file": stat /path/to/file: no such file or directory
error in exec: "/path/to/file": permission denied
Fixes#457
Detect if leading character in JSON payload is an array bracket. If
found, decode payload into an interface{} and then save the results into
payload["root"]. References to payload values would need to reference
the leading, "virtual" root node (i.e. "root.0.name").
Fixes#215
When attempting to match a JSON path for initial setup, it would be
helpful to know where the path failed. This change logs the failed
parameter node. For example, if you are trying to match path "a.b.d.e",
but you failed to include the "c" node, webhook will log an error
"parameter node not found: d.e" to assist in troubleshooting.
Default to TLS 1.2 and secure cipher suites.
Built for Go 1.13. Code in cipher_suites.go taken from Go tip commit
0ee22d9, which is scheduled for the upcoming Go 1.14 release. Once Go
1.14 is released, we can remove this file and use the stdlib.
Fixes#244
Refactored code to use switch-case statement over the `Content-Type` header and log unsupported content types instead of silently failing.
Also made the `x-www-form-urlencoded` content type handler more specific (as opposed to the previous code which looked for `form` occurence in the value),
as we need to use different logic for multipart forms, which we'll hopefully implement soon.
The issue with multipart forms that we have to handle first is that the files are being written to temporary files, and as such, for async hooks
webhook cannot guarantee they'll be available after we close the request; that, and the fact that we don't have code that will properly serialize
and pass such Golang objects to the script, as there are several fields which might be interesting to the end user.