Skip to content

Commit

Permalink
switch to reinvocationPolicy, default to Never
Browse files Browse the repository at this point in the history
  • Loading branch information
liggitt committed May 16, 2019
1 parent fe5bfe7 commit a5db4bd
Showing 1 changed file with 44 additions and 23 deletions.
67 changes: 44 additions & 23 deletions keps/sig-api-machinery/00xx-admission-webhooks-to-ga.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,9 @@ there is any change made by a mutating webhook on the first pass.
1. Initial mutating admission pass
2. If any webhook plugins returned patches modifying the object, do a second mutating admission pass
1. Run all in-tree mutating admission plugins
2. Run all applicable webhook mutating admission plugins that indicate they are idempotent
2. Run all applicable webhook mutating admission plugins that indicate they want to be reinvoked

Mutating plugins that are re-called must be idempotent, able to successfully process an object they have already
Mutating plugins that are reinvoked must be idempotent, able to successfully process an object they have already
admitted and potentially modified. This will be clearly documented in admission webhook documentation,
examples, and test guidelines. Mutating admission webhooks *should* already support this (since any
change they can make in an object could already exist in the user-provided object), and any webhooks
Expand All @@ -265,39 +265,42 @@ that do not are broken for some set of user input.
Note that idempotence (whether a webhook can successfully operate on its own output) is distinct from
the `sideEffects` indicator, which describes whether a webhook can safely be called in `dryRun` mode.

For compatibility, the re-call behavior will be opt-in for `v1beta1`, so `idempotent` will default to `false`.

In `v1`, newly registered mutating webhooks must be safe to re-call, so the `idempotent` field will be dropped.
`idempotent: false` in a `v1beta1` object will convert to a `deprecated.kubernetes.io/idempotent: "false"` annotation in `v1`.
Any annotation value other than `"false"` in a `v1` object (including a missing annotation) will convert to `idempotent: true` in `v1beta1`.
An annotation value of `deprecated.kubernetes.io/idempotent: "false"` will not be allowed when creating `v1` webhooks.
The reinvocation behavior will be opt-in, so `reinvocationPolicy` defaults to `"Never"`.

```golang
type MutatingWebhookConfiguration struct {
type Webhook struct {
...
// idempotent indicates whether these webhooks can successfully process their own output
// as part of a single admission evaluation. All webhooks *should* be idempotent, to be
// able to successfully handle arbitrary user input.
// reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation.
// Allowed values are "Never" and "IfNeeded".
//
// If false, the webhooks will not be called more than once in a single admission evaluation.
// Never: the webhook will not be called more than once in a single admission evaluation.
//
// If true, the webhooks may be called again as part of the admission evaluation (for example,
// if the object being admitted is modified by other admission plugins). Note that the number
// of re-invocations is not guaranteed to be exactly one. Also note that if the second round of
// evaluations results in modifications to the object being admitted, webhooks are not guaranteed
// to be invoked again. To validate an object after all mutations are completed, use a validating
// admission webhook.
// IfNeeded: the webhook will be called at least one additional time as part of the admission evaluation
// if the object being admitted is modified by other admission plugins after the initial webhook call.
// Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted.
// Note:
// * the number of additional invocations is not guaranteed to be exactly one.
// * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again.
// * webhooks that use this option may be reordered to minimize the number of additional invocations.
// * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.
//
// Defaults to false in v1beta1 to avoid breaking existing non-idempotent admission webhooks.
// Defaults to "Never".
// +optional
Idempotent *bool `json:"idempotent,omitempty"`
ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"`
}

type ReinvocationPolicyType string

var (
NeverReinvocationPolicy ReinvocationPolicyType = "Never"
IfNeededReinvocationPolicy ReinvocationPolicyType = "IfNeeded"
)
```

Although this problem can go deeper than two levels (for example, if the second mutating webhook added
a new structure based on the new `container`), a single re-run is sufficient for the current set of
in-tree plugins and webhook use-cases. If future use cases require additional or more targeted re-calls,
the `AdmissionReview` response can be enhanced to provide information to target those re-calls.
in-tree plugins and webhook use-cases. If future use cases require additional or more targeted reinvocations,
the `AdmissionReview` response can be enhanced to provide information to target those reinvocations.

### Passing {Operation}Option to Webhook

Expand Down Expand Up @@ -692,6 +695,24 @@ type Webhook struct {
// +optional
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"`

// reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation.
// Allowed values are "Never" and "IfNeeded".
//
// Never: the webhook will not be called more than once in a single admission evaluation.
//
// IfNeeded: the webhook will be called at least one additional time as part of the admission evaluation
// if the object being admitted is modified by other admission plugins after the initial webhook call.
// Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted.
// Note:
// * the number of additional invocations is not guaranteed to be exactly one.
// * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again.
// * webhooks that use this option may be reordered to minimize the number of additional invocations.
// * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.
//
// Defaults to "Never".
// +optional
ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"`

// NamespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
Expand Down

0 comments on commit a5db4bd

Please sign in to comment.