mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
182 lines
4.6 KiB
Go
182 lines
4.6 KiB
Go
package result
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// Indent acts for indenting in result hierarchy
|
|
type Indent string
|
|
|
|
const (
|
|
// SpaceIndent means 4 spaces
|
|
SpaceIndent Indent = " "
|
|
// TabIndent is a tab symbol
|
|
TabIndent Indent = "\t"
|
|
)
|
|
|
|
// Result is an interface that is used for result polymorphic behavior
|
|
type Result interface {
|
|
String() string
|
|
StringWithIndent(indent string) string
|
|
GetReason() Reason
|
|
ToError() error
|
|
}
|
|
|
|
// CompositeResult is used for result hierarchy
|
|
type CompositeResult struct {
|
|
Message string
|
|
Reason Reason
|
|
Children []Result
|
|
}
|
|
|
|
// RuleApplicationResult represents elementary result that is produced by PolicyEngine
|
|
// TODO: It can be used to create Kubernetes Results, so make method for this
|
|
type RuleApplicationResult struct {
|
|
PolicyRule string
|
|
Reason Reason
|
|
Messages []string
|
|
}
|
|
|
|
//NewRuleApplicationResult creates a new rule application result
|
|
func NewRuleApplicationResult(ruleName string) RuleApplicationResult {
|
|
return RuleApplicationResult{
|
|
PolicyRule: ruleName,
|
|
Reason: Success,
|
|
Messages: []string{},
|
|
}
|
|
}
|
|
|
|
// StringWithIndent makes result string where each
|
|
// line is prepended with specified indent
|
|
func (e *RuleApplicationResult) StringWithIndent(indent string) string {
|
|
message := fmt.Sprintf("%s* %s: policy rule - %s:\n", indent, e.Reason.String(), e.PolicyRule)
|
|
childrenIndent := indent + string(SpaceIndent)
|
|
for i, m := range e.Messages {
|
|
message += fmt.Sprintf("%s%d. %s\n", childrenIndent, i+1, m)
|
|
}
|
|
|
|
// remove last line feed
|
|
if 0 != len(message) {
|
|
message = message[:len(message)-1]
|
|
}
|
|
return message
|
|
}
|
|
|
|
// String makes result string
|
|
// for writing it to logs
|
|
func (e *RuleApplicationResult) String() string {
|
|
return e.StringWithIndent("")
|
|
}
|
|
|
|
// ToError returns the error if reason is not success
|
|
func (e *RuleApplicationResult) ToError() error {
|
|
if e.Reason != Success {
|
|
return fmt.Errorf(e.String())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//GetReason returns reason
|
|
func (e *RuleApplicationResult) GetReason() Reason {
|
|
return e.Reason
|
|
}
|
|
|
|
//AddMessagef Adds formatted message to this result
|
|
func (e *RuleApplicationResult) AddMessagef(message string, a ...interface{}) {
|
|
e.Messages = append(e.Messages, fmt.Sprintf(message, a...))
|
|
}
|
|
|
|
//FailWithMessagef Sets the Reason Failed and adds formatted message to this result
|
|
func (e *RuleApplicationResult) FailWithMessagef(message string, a ...interface{}) {
|
|
e.Reason = Failed
|
|
e.AddMessagef(message, a...)
|
|
}
|
|
|
|
//MergeWith Takes messages and higher reason from another RuleApplicationResult
|
|
func (e *RuleApplicationResult) MergeWith(other *RuleApplicationResult) {
|
|
if other != nil {
|
|
e.Messages = append(e.Messages, other.Messages...)
|
|
}
|
|
if other.Reason > e.Reason {
|
|
e.Reason = other.Reason
|
|
}
|
|
}
|
|
|
|
// StringWithIndent makes result string where each
|
|
// line is prepended with specified indent
|
|
func (e *CompositeResult) StringWithIndent(indent string) string {
|
|
childrenIndent := indent + string(SpaceIndent)
|
|
message := fmt.Sprintf("%s- %s: %s\n", indent, e.Reason, e.Message)
|
|
for _, res := range e.Children {
|
|
message += (res.StringWithIndent(childrenIndent) + "\n")
|
|
}
|
|
|
|
// remove last line feed
|
|
if 0 != len(message) {
|
|
message = message[:len(message)-1]
|
|
}
|
|
|
|
return message
|
|
}
|
|
|
|
// String makes result string
|
|
// for writing it to logs
|
|
func (e *CompositeResult) String() string {
|
|
return e.StringWithIndent("")
|
|
}
|
|
|
|
//ToError returns error if reason is not success
|
|
func (e *CompositeResult) ToError() error {
|
|
if e.Reason != Success {
|
|
return fmt.Errorf(e.String())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//GetReason returns reason
|
|
func (e *CompositeResult) GetReason() Reason {
|
|
return e.Reason
|
|
}
|
|
|
|
//NewPolicyApplicationResult creates a new policy application result
|
|
func NewPolicyApplicationResult(policyName string) Result {
|
|
return &CompositeResult{
|
|
Message: fmt.Sprintf("policy - %s:", policyName),
|
|
Reason: Success,
|
|
}
|
|
}
|
|
|
|
//NewAdmissionResult creates a new admission result
|
|
func NewAdmissionResult(requestUID string) Result {
|
|
return &CompositeResult{
|
|
Message: fmt.Sprintf("For resource with UID - %s:", requestUID),
|
|
Reason: Success,
|
|
}
|
|
}
|
|
|
|
// Append returns CompositeResult with target and source
|
|
// Or appends source to target if it is composite result
|
|
// If the source reason is more important than target reason,
|
|
// target takes the reason of the source.
|
|
func Append(target Result, source Result) Result {
|
|
targetReason := target.GetReason()
|
|
if targetReason < source.GetReason() {
|
|
targetReason = source.GetReason()
|
|
}
|
|
|
|
if composite, ok := target.(*CompositeResult); ok {
|
|
composite.Children = append(composite.Children, source)
|
|
composite.Reason = targetReason
|
|
return composite
|
|
}
|
|
|
|
composite := &CompositeResult{
|
|
Children: []Result{
|
|
target,
|
|
source,
|
|
},
|
|
Reason: targetReason,
|
|
}
|
|
|
|
return composite
|
|
}
|