wire up the webhook rejection metrics in webhook handlers
Kubernetes-commit: 620f5f2c587971be50cb27bb2a2d35209b3dc058
This commit is contained in:
parent
466e192e26
commit
8d86fef522
|
@ -136,10 +136,18 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib
|
|||
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
||||
rejected := false
|
||||
if err != nil {
|
||||
// ErrCallingWebhook is ignored if the webhook is configured to failopen.
|
||||
// Otherwise the request is rejected.
|
||||
if _, ok := err.(*webhookutil.ErrCallingWebhook); !ok || !ignoreClientCallFailures {
|
||||
switch err := err.(type) {
|
||||
case *webhookutil.ErrCallingWebhook:
|
||||
if !ignoreClientCallFailures {
|
||||
rejected = true
|
||||
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "admit", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionCallingWebhookError, 0)
|
||||
}
|
||||
case *webhookutil.ErrWebhookRejection:
|
||||
rejected = true
|
||||
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "admit", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionNoError, int(err.Status.ErrStatus.Code))
|
||||
default:
|
||||
rejected = true
|
||||
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "admit", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionAPIServerInternalError, 0)
|
||||
}
|
||||
}
|
||||
admissionmetrics.Metrics.ObserveWebhook(time.Since(t), rejected, versionedAttr.Attributes, "admit", hook.Name)
|
||||
|
@ -172,6 +180,9 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib
|
|||
klog.Warningf("Failed calling webhook, failing closed %v: %v", hook.Name, err)
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
if rejectionErr, ok := err.(*webhookutil.ErrWebhookRejection); ok {
|
||||
return rejectionErr.Status
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -257,7 +268,7 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
|||
}
|
||||
|
||||
if !result.Allowed {
|
||||
return false, webhookerrors.ToStatusErr(h.Name, result.Result)
|
||||
return false, &webhookutil.ErrWebhookRejection{Status: webhookerrors.ToStatusErr(h.Name, result.Result)}
|
||||
}
|
||||
|
||||
if len(result.Patch) == 0 {
|
||||
|
|
|
@ -104,10 +104,18 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attr
|
|||
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
||||
rejected := false
|
||||
if err != nil {
|
||||
// ErrCallingWebhook is ignored if the webhook is configured to failopen.
|
||||
// Otherwise the request is rejected.
|
||||
if _, ok := err.(*webhookutil.ErrCallingWebhook); !ok || !ignoreClientCallFailures {
|
||||
switch err := err.(type) {
|
||||
case *webhookutil.ErrCallingWebhook:
|
||||
if !ignoreClientCallFailures {
|
||||
rejected = true
|
||||
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "validating", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionCallingWebhookError, 0)
|
||||
}
|
||||
case *webhookutil.ErrWebhookRejection:
|
||||
rejected = true
|
||||
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "validating", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionNoError, int(err.Status.ErrStatus.Code))
|
||||
default:
|
||||
rejected = true
|
||||
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "validating", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionAPIServerInternalError, 0)
|
||||
}
|
||||
}
|
||||
admissionmetrics.Metrics.ObserveWebhook(time.Since(t), rejected, versionedAttr.Attributes, "validating", hook.Name)
|
||||
|
@ -127,6 +135,9 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attr
|
|||
return
|
||||
}
|
||||
|
||||
if rejectionErr, ok := err.(*webhookutil.ErrWebhookRejection); ok {
|
||||
err = rejectionErr.Status
|
||||
}
|
||||
klog.Warningf("rejected by webhook %q: %#v", hook.Name, err)
|
||||
errCh <- err
|
||||
}(relevantHooks[i])
|
||||
|
@ -219,5 +230,5 @@ func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Validati
|
|||
if result.Allowed {
|
||||
return nil
|
||||
}
|
||||
return webhookerrors.ToStatusErr(h.Name, result.Result)
|
||||
return &webhookutil.ErrWebhookRejection{Status: webhookerrors.ToStatusErr(h.Name, result.Result)}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,11 @@ limitations under the License.
|
|||
|
||||
package webhook
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
)
|
||||
|
||||
// ErrCallingWebhook is returned for transport-layer errors calling webhooks. It
|
||||
// represents a failure to talk to the webhook, not the webhook rejecting a
|
||||
|
@ -32,3 +36,12 @@ func (e *ErrCallingWebhook) Error() string {
|
|||
}
|
||||
return fmt.Sprintf("failed calling webhook %q; no further details available", e.WebhookName)
|
||||
}
|
||||
|
||||
// ErrWebhookRejection represents a webhook properly rejecting a request.
|
||||
type ErrWebhookRejection struct {
|
||||
Status *apierrors.StatusError
|
||||
}
|
||||
|
||||
func (e *ErrWebhookRejection) Error() string {
|
||||
return e.Status.Error()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue