1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-09 09:26:54 +00:00
kyverno/pkg/webhooks/resource/vpol/handler.go
Charles-Edouard Brétéché 4f63ef5bc1
feat: consider Warn validation action (#12081)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
2025-02-04 14:35:52 +00:00

67 lines
2.3 KiB
Go

package vpol
import (
"context"
"fmt"
"time"
"github.com/go-logr/logr"
celengine "github.com/kyverno/kyverno/pkg/cel/engine"
celpolicy "github.com/kyverno/kyverno/pkg/cel/policy"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
"go.uber.org/multierr"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
)
type handler struct {
context celpolicy.Context
engine celengine.Engine
}
func New(engine celengine.Engine, context celpolicy.Context) *handler {
return &handler{
context: context,
engine: engine,
}
}
func (h *handler) Validate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, failurePolicy string, startTime time.Time) handlers.AdmissionResponse {
response, err := h.engine.Handle(ctx, celengine.EngineRequest{
Request: &request.AdmissionRequest,
Context: h.context,
})
if err != nil {
return admissionutils.Response(request.UID, err)
}
return admissionResponse(response, request)
}
func admissionResponse(response celengine.EngineResponse, request handlers.AdmissionRequest) handlers.AdmissionResponse {
var errs []error
var warnings []string
for _, policy := range response.Policies {
if policy.Actions.Has(admissionregistrationv1.Deny) {
for _, rule := range policy.Rules {
switch rule.Status() {
case engineapi.RuleStatusFail:
errs = append(errs, fmt.Errorf("Policy %s rule %s failed: %s", policy.Policy.GetName(), rule.Name(), rule.Message()))
case engineapi.RuleStatusError:
errs = append(errs, fmt.Errorf("Policy %s rule %s error: %s", policy.Policy.GetName(), rule.Name(), rule.Message()))
}
}
}
if policy.Actions.Has(admissionregistrationv1.Warn) {
for _, rule := range policy.Rules {
switch rule.Status() {
case engineapi.RuleStatusFail:
warnings = append(warnings, fmt.Sprintf("Policy %s rule %s failed: %s", policy.Policy.GetName(), rule.Name(), rule.Message()))
case engineapi.RuleStatusError:
warnings = append(warnings, fmt.Sprintf("Policy %s rule %s error: %s", policy.Policy.GetName(), rule.Name(), rule.Message()))
}
}
}
}
return admissionutils.Response(request.UID, multierr.Combine(errs...), warnings...)
}