mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
refactor: simplify engine responses (#6804)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
04d410d321
commit
de00c78513
8 changed files with 49 additions and 51 deletions
|
@ -92,15 +92,18 @@ func Test_buildPolicyReports(t *testing.T) {
|
||||||
|
|
||||||
er := engineapi.EngineResponse{}
|
er := engineapi.EngineResponse{}
|
||||||
er.Policy = &policy
|
er.Policy = &policy
|
||||||
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RuleFail(
|
er.PolicyResponse.Add(
|
||||||
"pods-require-account",
|
engineapi.ExecutionStats{},
|
||||||
engineapi.Validation,
|
*engineapi.RuleFail(
|
||||||
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/"),
|
"pods-require-account",
|
||||||
)
|
engineapi.Validation,
|
||||||
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RulePass(
|
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/",
|
||||||
"pods-require-limits",
|
),
|
||||||
engineapi.Validation,
|
*engineapi.RulePass(
|
||||||
"validation rule 'pods-require-limits' passed."),
|
"pods-require-limits",
|
||||||
|
engineapi.Validation,
|
||||||
|
"validation rule 'pods-require-limits' passed.",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
info := kyvCommon.ProcessValidateEngineResponse(&policy, &er, "", rc, true, false)
|
info := kyvCommon.ProcessValidateEngineResponse(&policy, &er, "", rc, true, false)
|
||||||
|
@ -137,15 +140,17 @@ func Test_buildPolicyResults(t *testing.T) {
|
||||||
|
|
||||||
er := engineapi.EngineResponse{}
|
er := engineapi.EngineResponse{}
|
||||||
er.Policy = &policy
|
er.Policy = &policy
|
||||||
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RuleFail(
|
er.PolicyResponse.Add(
|
||||||
"pods-require-account",
|
engineapi.ExecutionStats{}, *engineapi.RuleFail(
|
||||||
engineapi.Validation,
|
"pods-require-account",
|
||||||
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/"),
|
engineapi.Validation,
|
||||||
)
|
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/",
|
||||||
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RulePass(
|
),
|
||||||
"pods-require-limits",
|
*engineapi.RulePass(
|
||||||
engineapi.Validation,
|
"pods-require-limits",
|
||||||
"validation rule 'pods-require-limits' passed."),
|
engineapi.Validation,
|
||||||
|
"validation rule 'pods-require-limits' passed.",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
info := kyvCommon.ProcessValidateEngineResponse(&policy, &er, "", rc, true, false)
|
info := kyvCommon.ProcessValidateEngineResponse(&policy, &er, "", rc, true, false)
|
||||||
|
|
|
@ -33,9 +33,9 @@ func generateSuccessEvents(log logr.Logger, ers ...engineapi.EngineResponse) (ev
|
||||||
|
|
||||||
func generateExceptionEvents(log logr.Logger, ers ...engineapi.EngineResponse) (eventInfos []event.Info) {
|
func generateExceptionEvents(log logr.Logger, ers ...engineapi.EngineResponse) (eventInfos []event.Info) {
|
||||||
for _, er := range ers {
|
for _, er := range ers {
|
||||||
for i, ruleResp := range er.PolicyResponse.Rules {
|
for _, ruleResp := range er.PolicyResponse.Rules {
|
||||||
if ruleResp.Status() == engineapi.RuleStatusSkip && ruleResp.IsException() {
|
if ruleResp.Status() == engineapi.RuleStatusSkip && ruleResp.IsException() {
|
||||||
eventInfos = append(eventInfos, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i], event.PolicyController)...)
|
eventInfos = append(eventInfos, event.NewPolicyExceptionEvents(er, ruleResp, event.PolicyController)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,11 @@ func generateFailEventsPerEr(log logr.Logger, er engineapi.EngineResponse) []eve
|
||||||
"namespace", er.Resource.GetNamespace(),
|
"namespace", er.Resource.GetNamespace(),
|
||||||
"name", er.Resource.GetName(),
|
"name", er.Resource.GetName(),
|
||||||
)
|
)
|
||||||
for i, rule := range er.PolicyResponse.Rules {
|
for _, rule := range er.PolicyResponse.Rules {
|
||||||
if rule.Status() != engineapi.RuleStatusPass && rule.Status() != engineapi.RuleStatusSkip {
|
if rule.Status() != engineapi.RuleStatusPass && rule.Status() != engineapi.RuleStatusSkip {
|
||||||
eventResource := event.NewResourceViolationEvent(event.PolicyController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i])
|
eventResource := event.NewResourceViolationEvent(event.PolicyController, event.PolicyViolation, er, rule)
|
||||||
eventInfos = append(eventInfos, eventResource)
|
eventInfos = append(eventInfos, eventResource)
|
||||||
eventPolicy := event.NewPolicyFailEvent(event.PolicyController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i], false)
|
eventPolicy := event.NewPolicyFailEvent(event.PolicyController, event.PolicyViolation, er, rule, false)
|
||||||
eventInfos = append(eventInfos, eventPolicy)
|
eventInfos = append(eventInfos, eventPolicy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,15 @@ type PolicyResponse struct {
|
||||||
Rules []RuleResponse
|
Rules []RuleResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *PolicyResponse) Add(stats ExecutionStats, response RuleResponse) {
|
func (pr *PolicyResponse) Add(stats ExecutionStats, responses ...RuleResponse) {
|
||||||
pr.Rules = append(pr.Rules, response.WithStats(stats))
|
for _, response := range responses {
|
||||||
status := response.Status()
|
pr.Rules = append(pr.Rules, response.WithStats(stats))
|
||||||
if status == RuleStatusPass || status == RuleStatusFail {
|
status := response.Status()
|
||||||
pr.Stats.RulesAppliedCount++
|
if status == RuleStatusPass || status == RuleStatusFail {
|
||||||
} else if status == RuleStatusError {
|
pr.Stats.RulesAppliedCount++
|
||||||
pr.Stats.RulesErrorCount++
|
} else if status == RuleStatusError {
|
||||||
|
pr.Stats.RulesErrorCount++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,7 @@ func (e *engine) verifyAndPatchImages(
|
||||||
engineapi.ImageVerify,
|
engineapi.ImageVerify,
|
||||||
)
|
)
|
||||||
matchedResource = resource
|
matchedResource = resource
|
||||||
stats := engineapi.NewExecutionStats(startTime, time.Now())
|
resp.Add(engineapi.NewExecutionStats(startTime, time.Now()), ruleResp...)
|
||||||
for _, ruleResp := range ruleResp {
|
|
||||||
resp.Add(stats, ruleResp)
|
|
||||||
}
|
|
||||||
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,10 +50,7 @@ func (e *engine) mutate(
|
||||||
engineapi.Mutation,
|
engineapi.Mutation,
|
||||||
)
|
)
|
||||||
matchedResource = resource
|
matchedResource = resource
|
||||||
stats := engineapi.NewExecutionStats(startTime, time.Now())
|
resp.Add(engineapi.NewExecutionStats(startTime, time.Now()), ruleResp...)
|
||||||
for _, ruleResp := range ruleResp {
|
|
||||||
resp.Add(stats, ruleResp)
|
|
||||||
}
|
|
||||||
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,10 +68,7 @@ func (e *engine) validate(
|
||||||
engineapi.Validation,
|
engineapi.Validation,
|
||||||
)
|
)
|
||||||
matchedResource = resource
|
matchedResource = resource
|
||||||
stats := engineapi.NewExecutionStats(startTime, time.Now())
|
resp.Add(engineapi.NewExecutionStats(startTime, time.Now()), ruleResp...)
|
||||||
for _, ruleResp := range ruleResp {
|
|
||||||
resp.Add(stats, ruleResp)
|
|
||||||
}
|
|
||||||
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPolicyFailEvent(source Source, reason Reason, engineResponse engineapi.EngineResponse, ruleResp *engineapi.RuleResponse, blocked bool) Info {
|
func NewPolicyFailEvent(source Source, reason Reason, engineResponse engineapi.EngineResponse, ruleResp engineapi.RuleResponse, blocked bool) Info {
|
||||||
return Info{
|
return Info{
|
||||||
Kind: getPolicyKind(engineResponse.Policy),
|
Kind: getPolicyKind(engineResponse.Policy),
|
||||||
Name: engineResponse.Policy.GetName(),
|
Name: engineResponse.Policy.GetName(),
|
||||||
|
@ -20,7 +20,7 @@ func NewPolicyFailEvent(source Source, reason Reason, engineResponse engineapi.E
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildPolicyEventMessage(resp *engineapi.RuleResponse, resource engineapi.ResourceSpec, blocked bool) string {
|
func buildPolicyEventMessage(resp engineapi.RuleResponse, resource engineapi.ResourceSpec, blocked bool) string {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
if resource.Namespace != "" {
|
if resource.Namespace != "" {
|
||||||
fmt.Fprintf(&b, "%s %s/%s", resource.Kind, resource.Namespace, resource.Name)
|
fmt.Fprintf(&b, "%s %s/%s", resource.Kind, resource.Namespace, resource.Name)
|
||||||
|
@ -68,7 +68,7 @@ func NewPolicyAppliedEvent(source Source, engineResponse engineapi.EngineRespons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResourceViolationEvent(source Source, reason Reason, engineResponse engineapi.EngineResponse, ruleResp *engineapi.RuleResponse) Info {
|
func NewResourceViolationEvent(source Source, reason Reason, engineResponse engineapi.EngineResponse, ruleResp engineapi.RuleResponse) Info {
|
||||||
var bldr strings.Builder
|
var bldr strings.Builder
|
||||||
defer bldr.Reset()
|
defer bldr.Reset()
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ func NewBackgroundSuccessEvent(policy, rule string, source Source, r *unstructur
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPolicyExceptionEvents(engineResponse engineapi.EngineResponse, ruleResp *engineapi.RuleResponse, source Source) []Info {
|
func NewPolicyExceptionEvents(engineResponse engineapi.EngineResponse, ruleResp engineapi.RuleResponse, source Source) []Info {
|
||||||
exception := ruleResp.Exception()
|
exception := ruleResp.Exception()
|
||||||
exceptionName, exceptionNamespace := exception.GetName(), exception.GetNamespace()
|
exceptionName, exceptionNamespace := exception.GetName(), exception.GetNamespace()
|
||||||
policyMessage := fmt.Sprintf("resource %s was skipped from rule %s due to policy exception %s/%s", resourceKey(engineResponse.PatchedResource), ruleResp.Name(), exceptionNamespace, exceptionName)
|
policyMessage := fmt.Sprintf("resource %s was skipped from rule %s due to policy exception %s/%s", resourceKey(engineResponse.PatchedResource), ruleResp.Name(), exceptionNamespace, exceptionName)
|
||||||
|
|
|
@ -20,20 +20,20 @@ func GenerateEvents(engineResponses []engineapi.EngineResponse, blocked bool) []
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !er.IsSuccessful() {
|
if !er.IsSuccessful() {
|
||||||
for i, ruleResp := range er.PolicyResponse.Rules {
|
for _, ruleResp := range er.PolicyResponse.Rules {
|
||||||
if ruleResp.Status() == engineapi.RuleStatusFail || ruleResp.Status() == engineapi.RuleStatusError {
|
if ruleResp.Status() == engineapi.RuleStatusFail || ruleResp.Status() == engineapi.RuleStatusError {
|
||||||
e := event.NewPolicyFailEvent(event.AdmissionController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i], blocked)
|
e := event.NewPolicyFailEvent(event.AdmissionController, event.PolicyViolation, er, ruleResp, blocked)
|
||||||
events = append(events, e)
|
events = append(events, e)
|
||||||
}
|
}
|
||||||
if !blocked {
|
if !blocked {
|
||||||
e := event.NewResourceViolationEvent(event.AdmissionController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i])
|
e := event.NewResourceViolationEvent(event.AdmissionController, event.PolicyViolation, er, ruleResp)
|
||||||
events = append(events, e)
|
events = append(events, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if er.IsSkipped() { // Handle PolicyException Event
|
} else if er.IsSkipped() { // Handle PolicyException Event
|
||||||
for i, ruleResp := range er.PolicyResponse.Rules {
|
for _, ruleResp := range er.PolicyResponse.Rules {
|
||||||
if ruleResp.Status() == engineapi.RuleStatusSkip && !blocked && ruleResp.IsException() {
|
if ruleResp.Status() == engineapi.RuleStatusSkip && !blocked && ruleResp.IsException() {
|
||||||
events = append(events, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i], event.AdmissionController)...)
|
events = append(events, event.NewPolicyExceptionEvents(er, ruleResp, event.AdmissionController)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !er.IsSkipped() {
|
} else if !er.IsSkipped() {
|
||||||
|
|
Loading…
Reference in a new issue