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

Add WebHookDockerDesktopServer #1054

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions docs/admission.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ each with its configuration parameters (see their descriptions):
accessing the server via a magical hostname ``host.k3d.internal``.
* :class:`kopf.WebhookMinikubeServer` for local Minikube clusters (even in VMs),
accessing the server via a magical hostname ``host.minikube.internal``.
* :class:`kopf.WebhookDockerDesktopServer` for the DockerDesktop cluster,
accessing the server via a magical hostname ``host.docker.internal``.

*Webhook tunnels* forward the webhook requests through external endpoints
usually to a locally running *webhook server*.
Expand Down
3 changes: 3 additions & 0 deletions examples/17-admission/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def config(settings: kopf.OperatorSettings, **_):
# Minikube-specific server that supports accessing from inside of a VM (a generated certificate):
settings.admission.server = kopf.WebhookMinikubeServer(port=1234, cadump=ROOT/'ca.pem')

# DockerDesktop-specific server that supports accessing from the host:
settings.admission.server = kopf.WebhookDockerDesktopServer(port=1234)

# Tunneling Kubernetes->ngrok->local server (anonymous, auto-loaded binary):
settings.admission.server = kopf.WebhookNgrokTunnel(path='/xyz', port=1234)

Expand Down
1 change: 1 addition & 0 deletions kopf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
WebhookServer,
WebhookK3dServer,
WebhookMinikubeServer,
WebhookDockerDesktopServer,
WebhookNgrokTunnel,
WebhookAutoServer,
WebhookAutoTunnel,
Expand Down
2 changes: 1 addition & 1 deletion kopf/_cogs/configs/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ class AdmissionSettings:
Kopf provides several webhook configs, servers, and tunnels out of the box
(they also serve as examples for implementing custom tunnels).
`kopf.WebhookServer`,
`kopf.WebhookK3dServer`, `kopf.WebhookMinikubeServer`,
`kopf.WebhookK3dServer`, `kopf.WebhookMinikubeServer`, `kopf.WebhookDockerDesktopServer`,
`kopf.WebhookNgrokTunnel`, `kopf.WebhookInletsTunnel`.

.. seealso::
Expand Down
19 changes: 19 additions & 0 deletions kopf/_kits/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,22 @@ class WebhookMinikubeServer(WebhookServer):
DEFAULT_HOST = 'host.minikube.internal'


class WebhookDockerDesktopServer(WebhookServer):
"""A tunnel from inside of Docker Desktop to its host where the operator is
running.

With this tunnel, a developer can develop the webhooks when fully
offline, since all the traffic is local and never leaves the host
machine.

The forwarding is maintained by Docker Desktop itself. This tunnel
only replaces the endpoints for the Kubernetes webhook and injects
an SSL certificate with proper CN/SANs --- to match Kubernetes's SSL
validity expectations.
"""
DEFAULT_HOST = "host.docker.internal"


class WebhookNgrokTunnel(webhacks.WebhookContextManager):
"""
Tunnel admission webhook request via an external tunnel: ngrok_.
Expand Down Expand Up @@ -582,6 +598,9 @@ async def guess_host() -> Optional[str]:
return WebhookK3dServer.DEFAULT_HOST
elif subject_cn == 'minikube' or issuer_cn == 'minikubeCA':
return WebhookMinikubeServer.DEFAULT_HOST
elif any(alt_name for alt_name in certpath.first.subject_alt_name_value.native if "docker" in alt_name):
return WebhookDockerDesktopServer.DEFAULT_HOST

else:
# The default timeouts & backoffs are used to retrieve the cluster
# version, not those from the operator. It is too difficult to get
Expand Down
4 changes: 3 additions & 1 deletion tests/admission/test_webhook_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

from kopf._core.engines.admission import AmbiguousResourceError, MissingDataError, \
UnknownResourceError, WebhookError
from kopf._kits.webhooks import WebhookK3dServer, WebhookMinikubeServer, WebhookServer
from kopf._kits.webhooks import WebhookDockerDesktopServer, WebhookK3dServer, \
WebhookMinikubeServer, WebhookServer


async def test_starts_as_http_ipv4(responder):
Expand Down Expand Up @@ -72,6 +73,7 @@ async def test_webhookserver_starts_as_https_with_provided_cert(
@pytest.mark.parametrize('cls, url', [
(WebhookK3dServer, 'https://host.k3d.internal:22533/p1/p2'),
(WebhookMinikubeServer, 'https://host.minikube.internal:22533/p1/p2'),
(WebhookDockerDesktopServer, 'https://host.docker.internal:22533/p1/p2'),
])
async def test_webhookserver_flavours_inject_hostnames(
certfile, pkeyfile, certpkey, responder, cls, url):
Expand Down