kubernetesValidating
This binding transforms a hook into a handler for ValidatingWebhookConfiguration. The Shell-operator creates ValidatingWebhookConfiguration, starts HTTPS server, and runs hooks to handle AdmissionReview requests.
Note: shell-operator use
admissionregistration.k8s.io/v1
, so Kubernetes 1.16+ is needed.
Syntax
configVersion: v1
onStartup: 10
kubernetes:
- name: myCrdObjects
...
kubernetesValidating:
- name: my-crd-validator.example.com
# include snapshots by binding names
includeSnapshotsFrom: ["myCrdObjects"]
# or use group name to include all snapshots in a group
group: "group name"
labelSelector: # equivalent of objectSelector
matchLabels:
label1: value1
...
namespace:
labelSelector: # equivalent of namespaceSelector
matchLabels:
label1: value1
...
matchExpressions:
- key: environment
operator: In
values: ["prod","staging"]
rules:
- apiVersions:
- v1
apiGroups:
- stable.example.com
resources:
- CronTab
operations:
- "*"
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1", "v1beta1"]
resources: ["deployments", "replicasets"]
scope: "Namespaced"
failurePolicy: Ignore | Fail (default)
sideEffects: None (default) | NoneOnDryRun
timeoutSeconds: 2 (default is 10)
matchConditions:
- name: "exclude-user"
expression: '("system:apiserver" != request.userInfo.username)'
Parameters
-
name
— a required parameter. It should be a domain with at least three segments separated by dots. -
includeSnapshotsFrom
— an array of names ofkubernetes
bindings in a hook. When specified, a list of monitored objects from these bindings will be added to the binding context in thesnapshots
field. -
group
— a key to include snapshots from a group ofschedule
andkubernetes
bindings. See grouping. -
labelSelector
— standard selector of objects by labels (examples of use). See objectSelector. -
namespace.labelSelector
— this filter works likelabelSelector
but for namespaces. See namespaceSelector. -
rules
— a required list of rules used to determine if a request to the Kubernetes API server should be sent to the hook. See Rules. -
failurePolicy
— defines how errors from the hook are handled. See Failure policy. Default isFail
. -
sideEffects
— determine whether the hook isdryRun
-aware. See side effects documentation. Default isNone
. -
timeoutSeconds
— a seconds API server should wait for a hook to respond before treating the call as a failure. See timeouts. Default is 10 (seconds). -
matchConditions
— an optional list of match conditions for fine-grained request filtering. Available only since v1.27 of Kubernetes.
As you can see, it is the close copy of a Webhook configuration. Differences are:
objectSelector
is alabelSelector
as in thekubernetes
binding.namespaceSelector
is anamespace.labelSelector
as in thekubernetes
binding.clientConfig
is managed by the Shell-operator. You should provide a Service for the Shell-operator HTTPS endpoint. See example 204-validating-webhook for possible solution.matchPolicy
is always “Equivalent”. See Matching requests: matchPolicy.- there are additional fields
group
andincludeSnapshotsFrom
to include snapshots in the binding context.
Example
configVersion: v1
kubernetesValidating:
- name: private-repo-policy.example.com
rules:
- apiGroups: ["stable.example.com"]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["crontabs"]
scope: "Namespaced"
The Shell-operator will execute hook with this configuration on every creation of CronTab object.
See example 204-validating-webhook.
Hook input and output
Note that the
group
parameter is only for including snapshots.kubernetesValidating
hook is never executed onschedule
orkubernetes
events with binding context with"type":"Group"
.
The hook receives a binding context and should return response in $VALIDATING_RESPONSE_PATH
.
$BINDING_CONTEXT_PATH file example:
[{
# Name as defined in binding configuration.
"binding": "my-crd-validator.example.com",
# Validating to distinguish from other events.
"type": "Validating",
# Snapshots as defined by includeSnapshotsFrom or group.
"snapshots": { ... }
# AdmissionReview object.
"review": {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"request": {
# Random uid uniquely identifying this admission call
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
# Fully-qualified group/version/kind of the incoming object
"kind": {"group":"autoscaling","version":"v1","kind":"Scale"},
# Fully-qualified group/version/kind of the resource being modified
"resource": {"group":"apps","version":"v1","resource":"deployments"},
# subresource, if the request is to a subresource
"subResource": "scale",
# Fully-qualified group/version/kind of the incoming object in the original request to the API server.
# This only differs from `kind` if the webhook specified `matchPolicy: Equivalent` and the
# original request to the API server was converted to a version the webhook registered for.
"requestKind": {"group":"autoscaling","version":"v1","kind":"Scale"},
# Fully-qualified group/version/kind of the resource being modified in the original request to the API server.
# This only differs from `resource` if the webhook specified `matchPolicy: Equivalent` and the
# original request to the API server was converted to a version the webhook registered for.
"requestResource": {"group":"apps","version":"v1","resource":"deployments"},
# subresource, if the request is to a subresource
# This only differs from `subResource` if the webhook specified `matchPolicy: Equivalent` and the
# original request to the API server was converted to a version the webhook registered for.
"requestSubResource": "scale",
# Name of the resource being modified
"name": "my-deployment",
# Namespace of the resource being modified, if the resource is namespaced (or is a Namespace object)
"namespace": "my-namespace",
# operation can be CREATE, UPDATE, DELETE, or CONNECT
"operation": "UPDATE",
"userInfo": {
# Username of the authenticated user making the request to the API server
"username": "admin",
# UID of the authenticated user making the request to the API server
"uid": "014fbff9a07c",
# Group memberships of the authenticated user making the request to the API server
"groups": ["system:authenticated","my-admin-group"],
# Arbitrary extra info associated with the user making the request to the API server.
# This is populated by the API server authentication layer and should be included
# if any SubjectAccessReview checks are performed by the webhook.
"extra": {
"some-key":["some-value1", "some-value2"]
}
},
# object is the new object being admitted.
# It is null for DELETE operations.
"object": {"apiVersion":"autoscaling/v1","kind":"Scale",...},
# oldObject is the existing object.
# It is null for CREATE and CONNECT operations.
"oldObject": {"apiVersion":"autoscaling/v1","kind":"Scale",...},
# options contains the options for the operation being admitted, like meta.k8s.io/v1 CreateOptions, UpdateOptions, or DeleteOptions.
# It is null for CONNECT operations.
"options": {"apiVersion":"meta.k8s.io/v1","kind":"UpdateOptions",...},
# dryRun indicates the API request is running in dry run mode and will not be persisted.
# Webhooks with side effects should avoid actuating those side effects when dryRun is true.
# See http://k8s.io/docs/reference/using-api/api-concepts/#make-a-dry-run-request for more details.
"dryRun": false
}
}
}]
Response example:
cat <<EOF > $VALIDATING_RESPONSE_PATH
{"allowed": true}
EOF
Allow with warnings (Kubernetes 1.19+):
cat <<EOF > $VALIDATING_RESPONSE_PATH
{"allowed": true, "warnings":["It might be risky because it is Tuesday", "It might be risky because your name starts with A"]}
EOF
Deny object creation and explain why:
cat <<EOF > $VALIDATING_RESPONSE_PATH
{"allowed": false, "message": "You cannot do this because it is Tuesday and your name starts with A"}
EOF
User will see an error message:
Error from server: admission webhook "policy.example.com" denied the request: You cannot do this because it is Tuesday and your name starts with A
Empty or invalid $VALIDATING_RESPONSE_PATH file is considered as "allowed": false
with a short message about the problem and a more verbose error in the log.
HTTP server and Kubernetes configuration
Shell-operator should create an HTTP endpoint with TLS support and register endpoints in the ValidatingWebhookConfiguration resource.
There should be a Service for shell-operator (see Availability).
Command line options:
--validating-webhook-configuration-name="shell-operator-hooks"
A name of a ValidatingWebhookConfiguration resource. Can be set with
$VALIDATING_WEBHOOK_CONFIGURATION_NAME.
--validating-webhook-service-name="shell-operator-validating-svc"
A name of a service used in ValidatingWebhookConfiguration. Can be set
with $VALIDATING_WEBHOOK_SERVICE_NAME.
--validating-webhook-server-cert="/validating-certs/tls.crt"
A path to a server certificate for service used in
ValidatingWebhookConfiguration. Can be set with
$VALIDATING_WEBHOOK_SERVER_CERT.
--validating-webhook-server-key="/validating-certs/tls.key"
A path to a server private key for service used in
ValidatingWebhookConfiguration. Can be set with
$VALIDATING_WEBHOOK_SERVER_KEY.
--validating-webhook-ca="/validating-certs/ca.crt"
A path to a ca certificate for ValidatingWebhookConfiguration. Can be set
with $VALIDATING_WEBHOOK_CA.
--validating-webhook-client-ca=VALIDATING-WEBHOOK-CLIENT-CA ...
A path to a server certificate for ValidatingWebhookConfiguration. Can be
set with $VALIDATING_WEBHOOK_CLIENT_CA.