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
|
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
||||||
rejected := false
|
rejected := false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ErrCallingWebhook is ignored if the webhook is configured to failopen.
|
switch err := err.(type) {
|
||||||
// Otherwise the request is rejected.
|
case *webhookutil.ErrCallingWebhook:
|
||||||
if _, ok := err.(*webhookutil.ErrCallingWebhook); !ok || !ignoreClientCallFailures {
|
if !ignoreClientCallFailures {
|
||||||
|
rejected = true
|
||||||
|
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "admit", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionCallingWebhookError, 0)
|
||||||
|
}
|
||||||
|
case *webhookutil.ErrWebhookRejection:
|
||||||
rejected = true
|
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)
|
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)
|
klog.Warningf("Failed calling webhook, failing closed %v: %v", hook.Name, err)
|
||||||
return apierrors.NewInternalError(err)
|
return apierrors.NewInternalError(err)
|
||||||
}
|
}
|
||||||
|
if rejectionErr, ok := err.(*webhookutil.ErrWebhookRejection); ok {
|
||||||
|
return rejectionErr.Status
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +268,7 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
||||||
}
|
}
|
||||||
|
|
||||||
if !result.Allowed {
|
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 {
|
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
|
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
||||||
rejected := false
|
rejected := false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ErrCallingWebhook is ignored if the webhook is configured to failopen.
|
switch err := err.(type) {
|
||||||
// Otherwise the request is rejected.
|
case *webhookutil.ErrCallingWebhook:
|
||||||
if _, ok := err.(*webhookutil.ErrCallingWebhook); !ok || !ignoreClientCallFailures {
|
if !ignoreClientCallFailures {
|
||||||
|
rejected = true
|
||||||
|
admissionmetrics.Metrics.ObserveWebhookRejection(hook.Name, "validating", string(versionedAttr.Attributes.GetOperation()), admissionmetrics.WebhookRejectionCallingWebhookError, 0)
|
||||||
|
}
|
||||||
|
case *webhookutil.ErrWebhookRejection:
|
||||||
rejected = true
|
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)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rejectionErr, ok := err.(*webhookutil.ErrWebhookRejection); ok {
|
||||||
|
err = rejectionErr.Status
|
||||||
|
}
|
||||||
klog.Warningf("rejected by webhook %q: %#v", hook.Name, err)
|
klog.Warningf("rejected by webhook %q: %#v", hook.Name, err)
|
||||||
errCh <- err
|
errCh <- err
|
||||||
}(relevantHooks[i])
|
}(relevantHooks[i])
|
||||||
|
@ -219,5 +230,5 @@ func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Validati
|
||||||
if result.Allowed {
|
if result.Allowed {
|
||||||
return nil
|
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
|
package webhook
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
)
|
||||||
|
|
||||||
// ErrCallingWebhook is returned for transport-layer errors calling webhooks. It
|
// ErrCallingWebhook is returned for transport-layer errors calling webhooks. It
|
||||||
// represents a failure to talk to the webhook, not the webhook rejecting a
|
// 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)
|
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