Skip to content

Commit

Permalink
Merge pull request #736 from nolar/webhook-docs
Browse files Browse the repository at this point in the history
Fix the admission webhooks' documentation
  • Loading branch information
nolar committed Apr 13, 2021
2 parents bf08b9f + 1066ea3 commit 2aee96f
Showing 1 changed file with 31 additions and 8 deletions.
39 changes: 31 additions & 8 deletions docs/admission.rst
Original file line number Diff line number Diff line change
Expand Up @@ -227,17 +227,27 @@ Unlike with regular handlers and their error handling logic (:doc:`/errors`),
the webhooks cannot do retries or backoffs. So, the ``backoff=``, ``errors=``,
``retries=``, ``timeout=`` options are not accepted on the admission handlers.

`kopf.PermanentError` and `kopf.TemporaryError` are treated ...TODO: how?

A special exception `kopf.AdmissionError` is provided to customize the status
code and the message of the admission review response.

All other exceptions, including `kopf.PermanentError` and `kopf.TemporaryError`,
equally fail the admission (be that validating or mutating admission).
However, they return the general HTTP code 500 (non-customisable).

One and only one error is returned to the user who make an API request.
In cases when Kubernetes makes several parallel requests to several webhooks
(typically with managed webhook configurations, the fastest error is used).
Within Kopf (usually with custom webhook servers/tunnels or self-made
non-managed webhook configurations), errors are prioritised: first, admission
errors, then permanent errors, then temporary errors, then arbitrary errors
are used to select the only error to report in the admission review response.

.. code-block:: python
@kopf.on.validate('kopfexamples')
def validate1(spec, **_):
if spec.get('field') == 'value':
raise kopf.AdmissionError("Meh! I don't like it. Change the field.")
raise kopf.AdmissionError("Meh! I don't like it. Change the field.", code=400)
The admission errors look like this (manually indented for readability):

Expand Down Expand Up @@ -396,7 +406,7 @@ For simplicity, Kopf does not authenticate webhook clients.

However, Kopf's built-in webhook servers & tunnels extract the very basic
request information and pass it to the admission handlers
for additional verifications and possibly for authentification:
for additional verification and possibly for authentification:

* :kwarg:`headers` (``Mapping[str, str]``) contains all HTTPS headers,
including ``Authorization: Basic ...``, ``Authorization: Bearer ...``.
Expand Down Expand Up @@ -426,7 +436,10 @@ An example of a self-signed peer certificate presented to ``sslpeer``:
'notBefore': 'Mar 7 17:12:20 2021 GMT',
'notAfter': 'Mar 7 17:12:20 2022 GMT'}
To reproduce this without configuring apiservers:
To reproduce these examples without configuring the Kubernetes apiservers
but only Kopf & CLI tools, do the following:

Step 1: Generate a self-signed ceritificate to be used as a client certificate:

.. code-block:: bash
Expand All @@ -439,6 +452,10 @@ To reproduce this without configuring apiservers:
# Common Name (eg, fully qualified host name) []:Example Common Name
# Email Address []:example@kopf.dev
Step 2: Start an operator with the certificate as a CA (for simplicity;
in normal setups, there is a separate CA, which signs the client certificates;
explaining this topic is beyond the scope of this framework's documentation):

.. code-block:: python
import kopf
Expand All @@ -453,6 +470,8 @@ To reproduce this without configuring apiservers:
print(f'{headers=}')
print(f'{sslpeer=}')
Step 3: Save the admission review payload into a local file:

.. code-block:: bash
cat >review.json << EOF
Expand Down Expand Up @@ -480,6 +499,10 @@ To reproduce this without configuring apiservers:
}
EOF
Step 4: Send the admission review payload to the operator's webhook server
using the generated client certificate, observe the client identity printed
to stdout by the webhook server and returned in the warnings:
.. code-block:: bash
curl --insecure --cert client-cert.pem --key client-key.pem https://ussser:passsw@localhost:54321 -d @review.json
Expand All @@ -488,8 +511,8 @@ To reproduce this without configuring apiservers:
# "allowed": true,
# "warnings": ["SSL peer is Example Common Name."]}}
When and if needed, the operator developers can implement their servers/tunnels
with their customised authentication methods.
Using this data, operator developers can implement servers/tunnels
with custom authentication methods when and if needed.
Debugging with SSL
Expand Down Expand Up @@ -552,7 +575,7 @@ do not support HTTPS tunnelling (or require paid subscriptions):
@kopf.on.startup()
def config(settings: kopf.OperatorSettings, **_):
settings.admission.server = kopf.¶ver(insecure=True)
settings.admission.server = kopf.WebhookServer(insecure=True)
Custom servers/tunnels
Expand Down

0 comments on commit 2aee96f

Please sign in to comment.