mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Configurable success events on policies & resources. Generating failure events on policies by default. (#1939)
* Remove unused event.Reason const Signed-off-by: Velkov <valentin.velkov@sap.com> * Generate failure events on policies Signed-off-by: Velkov <valentin.velkov@sap.com> * Generate success events on policy Signed-off-by: Velkov <valentin.velkov@sap.com> * Introduce 'generateSuccessEvents' flag Signed-off-by: Velkov <valentin.velkov@sap.com> * Unit tests & chart fix Signed-off-by: Velkov <valentin.velkov@sap.com>
This commit is contained in:
parent
436d44050b
commit
63f4c9a884
55 changed files with 336 additions and 113 deletions
|
@ -20,4 +20,7 @@ data:
|
|||
{{- if .Values.config.webhooks }}
|
||||
webhooks: {{ .Values.config.webhooks | toJson | quote }}
|
||||
{{- end -}}
|
||||
{{- if .Values.config.generateSuccessEvents }}
|
||||
generateSuccessEvents: {{ .Values.config.generateSuccessEvents | quote }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
|
|
@ -146,7 +146,7 @@ config:
|
|||
# will be forwarded to the webhookconfigurations.
|
||||
webhooks:
|
||||
# webhooks: [{"namespaceSelector":{"matchExpressions":[{"key":"environment","operator":"In","values":["prod"]}]}}]
|
||||
|
||||
generateSuccessEvents: 'false'
|
||||
# existingConfig: init-config
|
||||
|
||||
service:
|
||||
|
|
|
@ -179,6 +179,7 @@ func main() {
|
|||
eventGenerator := event.NewEventGenerator(
|
||||
client,
|
||||
pInformer.Kyverno().V1().ClusterPolicies(),
|
||||
pInformer.Kyverno().V1().Policies(),
|
||||
rCache,
|
||||
log.Log.WithName("EventGenerator"))
|
||||
|
||||
|
|
|
@ -3462,6 +3462,7 @@ subjects:
|
|||
apiVersion: v1
|
||||
data:
|
||||
excludeGroupRole: system:serviceaccounts:kube-system,system:nodes,system:kube-scheduler
|
||||
generateSuccessEvents: "false"
|
||||
resourceFilters: '[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][SelfSubjectAccessReview,*,*][*,kyverno,*][Binding,*,*][ReplicaSet,*,*][ReportChangeRequest,*,*][ClusterReportChangeRequest,*,*][PolicyReport,*,*][ClusterPolicyReport,*,*]'
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
|
|
|
@ -3311,6 +3311,7 @@ subjects:
|
|||
apiVersion: v1
|
||||
data:
|
||||
excludeGroupRole: system:serviceaccounts:kube-system,system:nodes,system:kube-scheduler
|
||||
generateSuccessEvents: "false"
|
||||
resourceFilters: '[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][SelfSubjectAccessReview,*,*][*,kyverno,*][Binding,*,*][ReplicaSet,*,*][ReportChangeRequest,*,*][ClusterReportChangeRequest,*,*][PolicyReport,*,*][ClusterPolicyReport,*,*]'
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
data:
|
||||
resourceFilters: '[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][SelfSubjectAccessReview,*,*][*,kyverno,*][Binding,*,*][ReplicaSet,*,*][ReportChangeRequest,*,*][ClusterReportChangeRequest,*,*][PolicyReport,*,*][ClusterPolicyReport,*,*]'
|
||||
excludeGroupRole: 'system:serviceaccounts:kube-system,system:nodes,system:kube-scheduler'
|
||||
generateSuccessEvents: 'false'
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
|
|
1
go.mod
1
go.mod
|
@ -25,6 +25,7 @@ require (
|
|||
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a
|
||||
github.com/mattn/go-runewidth v0.0.7 // indirect
|
||||
github.com/minio/pkg v1.0.4
|
||||
github.com/mitchellh/mapstructure v1.3.2 // indirect
|
||||
github.com/onsi/ginkgo v1.14.1
|
||||
github.com/onsi/gomega v1.10.2
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -816,6 +816,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
|||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
|
@ -37,6 +38,7 @@ type ConfigData struct {
|
|||
excludeUsername []string
|
||||
restrictDevelopmentUsername []string
|
||||
webhooks []WebhookConfig
|
||||
generateSuccessEvents bool
|
||||
cmSycned cache.InformerSynced
|
||||
reconcilePolicyReport chan<- bool
|
||||
updateWebhookConfigurations chan<- bool
|
||||
|
@ -83,6 +85,13 @@ func (cd *ConfigData) GetExcludeUsername() []string {
|
|||
return cd.excludeUsername
|
||||
}
|
||||
|
||||
// GetGenerateSuccessEvents return if should generate success events
|
||||
func (cd *ConfigData) GetGenerateSuccessEvents() bool {
|
||||
cd.mux.RLock()
|
||||
defer cd.mux.RUnlock()
|
||||
return cd.generateSuccessEvents
|
||||
}
|
||||
|
||||
// FilterNamespaces filters exclude namespace
|
||||
func (cd *ConfigData) FilterNamespaces(namespaces []string) []string {
|
||||
var results []string
|
||||
|
@ -110,6 +119,7 @@ type Interface interface {
|
|||
ToFilter(kind, namespace, name string) bool
|
||||
GetExcludeGroupRole() []string
|
||||
GetExcludeUsername() []string
|
||||
GetGenerateSuccessEvents() bool
|
||||
RestrictDevelopmentUsername() []string
|
||||
FilterNamespaces(namespaces []string) []string
|
||||
GetWebhooks() []WebhookConfig
|
||||
|
@ -290,6 +300,23 @@ func (cd *ConfigData) load(cm v1.ConfigMap) (reconcilePolicyReport, updateWebhoo
|
|||
updateWebhook = true
|
||||
}
|
||||
}
|
||||
|
||||
generateSuccessEvents, ok := cm.Data["generateSuccessEvents"]
|
||||
if !ok {
|
||||
logger.V(4).Info("configuration: No generateSuccessEvents defined in ConfigMap")
|
||||
} else {
|
||||
generateSuccessEvents, err := strconv.ParseBool(generateSuccessEvents)
|
||||
if err != nil {
|
||||
logger.V(4).Info("configuration: generateSuccessEvents must be either true/false")
|
||||
} else if generateSuccessEvents == cd.generateSuccessEvents {
|
||||
logger.V(4).Info("generateSuccessEvents did not change")
|
||||
} else {
|
||||
logger.V(2).Info("Updated generateSuccessEvents", "oldGenerateSuccessEvents", cd.generateSuccessEvents, "newGenerateSuccessEvents", generateSuccessEvents)
|
||||
cd.generateSuccessEvents = generateSuccessEvents
|
||||
reconcilePolicyReport = true
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -333,6 +360,7 @@ func (cd *ConfigData) unload(cm v1.ConfigMap) {
|
|||
cd.excludeGroupRole = []string{}
|
||||
cd.excludeGroupRole = append(cd.excludeGroupRole, defaultExcludeGroupRole...)
|
||||
cd.excludeUsername = []string{}
|
||||
cd.generateSuccessEvents = false
|
||||
}
|
||||
|
||||
type k8Resource struct {
|
||||
|
|
|
@ -25,7 +25,10 @@ func filterRules(policyContext *PolicyContext, startTime time.Time) *response.En
|
|||
apiVersion := policyContext.NewResource.GetAPIVersion()
|
||||
resp := &response.EngineResponse{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: policyContext.Policy.Name,
|
||||
Policy: response.PolicySpec{
|
||||
Name: policyContext.Policy.GetName(),
|
||||
Namespace: policyContext.Policy.GetNamespace(),
|
||||
},
|
||||
PolicyStats: response.PolicyStats{
|
||||
PolicyExecutionTimestamp: startTime.Unix(),
|
||||
},
|
||||
|
|
|
@ -134,7 +134,8 @@ func startMutateResultResponse(resp *response.EngineResponse, policy kyverno.Clu
|
|||
return
|
||||
}
|
||||
|
||||
resp.PolicyResponse.Policy = policy.Name
|
||||
resp.PolicyResponse.Policy.Name = policy.GetName()
|
||||
resp.PolicyResponse.Policy.Namespace = policy.GetNamespace()
|
||||
resp.PolicyResponse.Resource.Name = resource.GetName()
|
||||
resp.PolicyResponse.Resource.Namespace = resource.GetNamespace()
|
||||
resp.PolicyResponse.Resource.Kind = resource.GetKind()
|
||||
|
|
|
@ -17,8 +17,8 @@ type EngineResponse struct {
|
|||
|
||||
//PolicyResponse policy application response
|
||||
type PolicyResponse struct {
|
||||
// policy name
|
||||
Policy string `json:"policy"`
|
||||
// policy details
|
||||
Policy PolicySpec `json:"policy"`
|
||||
// resource details
|
||||
Resource ResourceSpec `json:"resource"`
|
||||
// policy statistics
|
||||
|
@ -29,6 +29,12 @@ type PolicyResponse struct {
|
|||
ValidationFailureAction string
|
||||
}
|
||||
|
||||
//PolicySpec policy
|
||||
type PolicySpec struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
//ResourceSpec resource action applied on
|
||||
type ResourceSpec struct {
|
||||
Kind string `json:"kind"`
|
||||
|
@ -95,6 +101,16 @@ func (er EngineResponse) IsSuccessful() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
//IsFailed checks if any rule has succeeded or not
|
||||
func (er EngineResponse) IsFailed() bool {
|
||||
for _, r := range er.PolicyResponse.Rules {
|
||||
if r.Success {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//GetPatches returns all the patches joined
|
||||
func (er EngineResponse) GetPatches() [][]byte {
|
||||
var patches [][]byte
|
||||
|
|
|
@ -60,7 +60,8 @@ func buildResponse(logger logr.Logger, ctx *PolicyContext, resp *response.Engine
|
|||
resp.PatchedResource = resource
|
||||
}
|
||||
|
||||
resp.PolicyResponse.Policy = ctx.Policy.Name
|
||||
resp.PolicyResponse.Policy.Name = ctx.Policy.GetName()
|
||||
resp.PolicyResponse.Policy.Namespace = ctx.Policy.GetNamespace()
|
||||
resp.PolicyResponse.Resource.Name = resp.PatchedResource.GetName()
|
||||
resp.PolicyResponse.Resource.Namespace = resp.PatchedResource.GetNamespace()
|
||||
resp.PolicyResponse.Resource.Kind = resp.PatchedResource.GetKind()
|
||||
|
|
|
@ -11,7 +11,7 @@ func TestPositive(t *testing.T) {
|
|||
resourceName := "test_resource"
|
||||
ruleName := "test_rule"
|
||||
expectedMsg := fmt.Sprintf("Rule(s) '%s' failed to apply on resource %s", ruleName, resourceName)
|
||||
msg, err := getEventMsg(FPolicyApplyFailed, ruleName, resourceName)
|
||||
msg, err := getEventMsg(FPolicyApply, ruleName, resourceName)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, expectedMsg, msg)
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ func TestPositive(t *testing.T) {
|
|||
// passing incorrect args
|
||||
func TestIncorrectArgs(t *testing.T) {
|
||||
resourceName := "test_resource"
|
||||
_, err := getEventMsg(FPolicyApplyFailed, resourceName, "extra_args1", "extra_args2")
|
||||
_, err := getEventMsg(FPolicyApply, resourceName, "extra_args1", "extra_args2")
|
||||
assert.Error(t, err, "message expects 2 arguments, but 3 arguments passed")
|
||||
}
|
||||
|
|
|
@ -26,8 +26,12 @@ import (
|
|||
type Generator struct {
|
||||
client *client.Client
|
||||
// list/get cluster policy
|
||||
pLister kyvernolister.ClusterPolicyLister
|
||||
cpLister kyvernolister.ClusterPolicyLister
|
||||
// returns true if the cluster policy store has been synced at least once
|
||||
cpSynced cache.InformerSynced
|
||||
// list/get policy
|
||||
pLister kyvernolister.PolicyLister
|
||||
// returns true if the policy store has been synced at least once
|
||||
pSynced cache.InformerSynced
|
||||
// queue to store event generation requests
|
||||
queue workqueue.RateLimitingInterface
|
||||
|
@ -47,13 +51,15 @@ type Interface interface {
|
|||
}
|
||||
|
||||
//NewEventGenerator to generate a new event controller
|
||||
func NewEventGenerator(client *client.Client, pInformer kyvernoinformer.ClusterPolicyInformer, resCache resourcecache.ResourceCache, log logr.Logger) *Generator {
|
||||
func NewEventGenerator(client *client.Client, cpInformer kyvernoinformer.ClusterPolicyInformer, pInformer kyvernoinformer.PolicyInformer, resCache resourcecache.ResourceCache, log logr.Logger) *Generator {
|
||||
|
||||
gen := Generator{
|
||||
client: client,
|
||||
cpLister: cpInformer.Lister(),
|
||||
cpSynced: cpInformer.Informer().HasSynced,
|
||||
pLister: pInformer.Lister(),
|
||||
queue: workqueue.NewNamedRateLimitingQueue(rateLimiter(), eventWorkQueueName),
|
||||
pSynced: pInformer.Informer().HasSynced,
|
||||
queue: workqueue.NewNamedRateLimitingQueue(rateLimiter(), eventWorkQueueName),
|
||||
policyCtrRecorder: initRecorder(client, PolicyController, log),
|
||||
admissionCtrRecorder: initRecorder(client, AdmissionController, log),
|
||||
genPolicyRecorder: initRecorder(client, GeneratePolicyController, log),
|
||||
|
@ -112,7 +118,7 @@ func (gen *Generator) Run(workers int, stopCh <-chan struct{}) {
|
|||
logger.Info("start")
|
||||
defer logger.Info("shutting down")
|
||||
|
||||
if !cache.WaitForCacheSync(stopCh, gen.pSynced) {
|
||||
if !cache.WaitForCacheSync(stopCh, gen.cpSynced, gen.pSynced) {
|
||||
logger.Info("failed to sync informer cache")
|
||||
}
|
||||
|
||||
|
@ -183,7 +189,13 @@ func (gen *Generator) syncHandler(key Info) error {
|
|||
switch key.Kind {
|
||||
case "ClusterPolicy":
|
||||
//TODO: policy is clustered resource so wont need namespace
|
||||
robj, err = gen.pLister.Get(key.Name)
|
||||
robj, err = gen.cpLister.Get(key.Name)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to get cluster policy", "name", key.Name)
|
||||
return err
|
||||
}
|
||||
case "Policy":
|
||||
robj, err = gen.pLister.Policies(key.Namespace).Get(key.Name)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to get policy", "name", key.Name)
|
||||
return err
|
||||
|
@ -200,6 +212,9 @@ func (gen *Generator) syncHandler(key Info) error {
|
|||
|
||||
// set the event type based on reason
|
||||
eventType := v1.EventTypeWarning
|
||||
if key.Reason == PolicyApplied.String() {
|
||||
eventType = v1.EventTypeNormal
|
||||
}
|
||||
|
||||
// based on the source of event generation, use different event recorders
|
||||
switch key.Source {
|
||||
|
|
|
@ -10,20 +10,16 @@ type MsgKey int
|
|||
|
||||
//Message id for pre-defined messages
|
||||
const (
|
||||
FPolicyApplyBlockCreate MsgKey = iota
|
||||
FPolicyApplyBlockUpdate
|
||||
FPolicyBlockResourceUpdate
|
||||
FPolicyApplyFailed
|
||||
FResourcePolicyFailed
|
||||
FPolicyApply = iota
|
||||
FResourcePolicyApply
|
||||
SPolicyApply
|
||||
)
|
||||
|
||||
func (k MsgKey) String() string {
|
||||
return [...]string{
|
||||
"Resource %s creation blocked by rule(s) %s",
|
||||
"Rule(s) '%s' of policy '%s' blocked update of the resource",
|
||||
"Resource %s update blocked by rule(s) %s",
|
||||
"Rule(s) '%s' failed to apply on resource %s",
|
||||
"Rule(s) '%s' of policy '%s' failed to apply on the resource",
|
||||
"Rule(s) '%s' successfully applied on resource %s",
|
||||
}[k]
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ type Reason int
|
|||
const (
|
||||
//PolicyViolation there is a violation of policy
|
||||
PolicyViolation Reason = iota
|
||||
//RequestBlocked the request to create/update the resource was blocked( generated from admission-controller)
|
||||
RequestBlocked
|
||||
//PolicyApplied policy applied
|
||||
PolicyApplied
|
||||
//PolicyFailed policy failed
|
||||
PolicyFailed
|
||||
)
|
||||
|
@ -15,7 +15,7 @@ const (
|
|||
func (r Reason) String() string {
|
||||
return [...]string{
|
||||
"PolicyViolation",
|
||||
"RequestBlocked",
|
||||
"PolicyApplied",
|
||||
"PolicyFailed",
|
||||
}[r]
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ func (c *Controller) applyGenerate(resource unstructured.Unstructured, gr kyvern
|
|||
if !r.Success {
|
||||
logger.V(4).Info("querying all generate requests")
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{
|
||||
"generate.kyverno.io/policy-name": engineResponse.PolicyResponse.Policy,
|
||||
"generate.kyverno.io/policy-name": engineResponse.PolicyResponse.Policy.Name,
|
||||
"generate.kyverno.io/resource-name": engineResponse.PolicyResponse.Resource.Name,
|
||||
"generate.kyverno.io/resource-kind": engineResponse.PolicyResponse.Resource.Kind,
|
||||
"generate.kyverno.io/resource-namespace": engineResponse.PolicyResponse.Resource.Namespace,
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
)
|
||||
|
||||
func failedEvents(err error, gr kyverno.GenerateRequest, resource unstructured.Unstructured) []event.Info {
|
||||
|
||||
re := event.Info{}
|
||||
re.Kind = resource.GetKind()
|
||||
re.Namespace = resource.GetNamespace()
|
||||
|
|
|
@ -26,7 +26,7 @@ var engineResponses = []*response.EngineResponse{
|
|||
},
|
||||
},
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy1",
|
||||
Policy: response.PolicySpec{Name: "policy1"},
|
||||
Resource: response.ResourceSpec{Name: "policy1-pod"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ var engineResponses = []*response.EngineResponse{
|
|||
},
|
||||
},
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "clusterpolicy2",
|
||||
Policy: response.PolicySpec{Name: "clusterpolicy2"},
|
||||
Resource: response.ResourceSpec{Name: "policy2-clusterrole"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
|
|
|
@ -225,7 +225,7 @@ func buildPolicyResults(resps []*response.EngineResponse, testResults []TestResu
|
|||
results := make(map[string]report.PolicyReportResult)
|
||||
infos := policyreport.GeneratePRsFromEngineResponse(resps, log.Log)
|
||||
for _, resp := range resps {
|
||||
policyName := resp.PolicyResponse.Policy
|
||||
policyName := resp.PolicyResponse.Policy.Name
|
||||
resourceName := resp.PolicyResponse.Resource.Name
|
||||
var rules []string
|
||||
for _, rule := range resp.PolicyResponse.Rules {
|
||||
|
|
|
@ -95,7 +95,7 @@ func (pc *PolicyController) applyAndReportPerNamespace(policy *kyverno.ClusterPo
|
|||
*metricAlreadyRegistered = true
|
||||
}
|
||||
|
||||
pc.report(policy.Name, engineResponses, logger)
|
||||
pc.report(engineResponses, logger)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) registerPolicyRuleResultsMetricValidationBS(logger logr.Logger, policy kyverno.ClusterPolicy, engineResponse response.EngineResponse, backgroundScanTimestamp int64) {
|
||||
|
|
|
@ -17,10 +17,15 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
func (pc *PolicyController) report(policy string, engineResponses []*response.EngineResponse, logger logr.Logger) {
|
||||
eventInfos := generateEvents(logger, engineResponses)
|
||||
func (pc *PolicyController) report(engineResponses []*response.EngineResponse, logger logr.Logger) {
|
||||
eventInfos := generateFailEvents(logger, engineResponses)
|
||||
pc.eventGen.Add(eventInfos...)
|
||||
|
||||
if pc.configHandler.GetGenerateSuccessEvents() {
|
||||
successEventInfos := generateSuccessEvents(logger, engineResponses)
|
||||
pc.eventGen.Add(successEventInfos...)
|
||||
}
|
||||
|
||||
pvInfos := policyreport.GeneratePRsFromEngineResponse(engineResponses, logger)
|
||||
|
||||
// as engineResponses holds the results for all matched resources in one namespace
|
||||
|
@ -131,22 +136,43 @@ func (pc *PolicyController) requeuePolicies() {
|
|||
}
|
||||
}
|
||||
|
||||
func generateEvents(log logr.Logger, ers []*response.EngineResponse) []event.Info {
|
||||
var eventInfos []event.Info
|
||||
func generateSuccessEvents(log logr.Logger, ers []*response.EngineResponse) (eventInfos []event.Info) {
|
||||
for _, er := range ers {
|
||||
if er.IsSuccessful() {
|
||||
continue
|
||||
logger := log.WithValues("policy", er.PolicyResponse.Policy, "kind", er.PolicyResponse.Resource.Kind, "namespace", er.PolicyResponse.Resource.Namespace, "name", er.PolicyResponse.Resource.Name)
|
||||
logger.V(4).Info("reporting success results for policy")
|
||||
|
||||
if !er.IsFailed() {
|
||||
// generate event on policy for success rules
|
||||
logger.V(4).Info("generating event on policy for success rules")
|
||||
e := event.Info{}
|
||||
kind := "ClusterPolicy"
|
||||
if er.PolicyResponse.Policy.Namespace != "" {
|
||||
kind = "Policy"
|
||||
}
|
||||
e.Kind = kind
|
||||
e.Namespace = er.PolicyResponse.Policy.Namespace
|
||||
e.Name = er.PolicyResponse.Policy.Name
|
||||
e.Reason = event.PolicyApplied.String()
|
||||
e.Source = event.PolicyController
|
||||
e.Message = fmt.Sprintf("rules '%v' successfully applied on resource '%s/%s/%s'", er.GetSuccessRules(), er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
|
||||
eventInfos = append(eventInfos, e)
|
||||
}
|
||||
eventInfos = append(eventInfos, generateEventsPerEr(log, er)...)
|
||||
}
|
||||
return eventInfos
|
||||
}
|
||||
|
||||
func generateEventsPerEr(log logr.Logger, er *response.EngineResponse) []event.Info {
|
||||
func generateFailEvents(log logr.Logger, ers []*response.EngineResponse) (eventInfos []event.Info) {
|
||||
for _, er := range ers {
|
||||
eventInfos = append(eventInfos, generateFailEventsPerEr(log, er)...)
|
||||
}
|
||||
return eventInfos
|
||||
}
|
||||
|
||||
func generateFailEventsPerEr(log logr.Logger, er *response.EngineResponse) []event.Info {
|
||||
var eventInfos []event.Info
|
||||
|
||||
logger := log.WithValues("policy", er.PolicyResponse.Policy, "kind", er.PolicyResponse.Resource.Kind, "namespace", er.PolicyResponse.Resource.Namespace, "name", er.PolicyResponse.Resource.Name)
|
||||
logger.V(4).Info("reporting results for policy")
|
||||
logger := log.WithValues("policy", er.PolicyResponse.Policy.Name, "kind", er.PolicyResponse.Resource.Kind, "namespace", er.PolicyResponse.Resource.Namespace, "name", er.PolicyResponse.Resource.Name)
|
||||
logger.V(4).Info("reporting fail results for policy")
|
||||
|
||||
for _, rule := range er.PolicyResponse.Rules {
|
||||
if rule.Success {
|
||||
|
@ -160,10 +186,43 @@ func generateEventsPerEr(log logr.Logger, er *response.EngineResponse) []event.I
|
|||
e.Name = er.PolicyResponse.Resource.Name
|
||||
e.Reason = event.PolicyViolation.String()
|
||||
e.Source = event.PolicyController
|
||||
e.Message = fmt.Sprintf("policy '%s' (%s) rule '%s' failed. %v", er.PolicyResponse.Policy, rule.Type, rule.Name, rule.Message)
|
||||
e.Message = fmt.Sprintf("policy '%s' (%s) rule '%s' failed. %v", er.PolicyResponse.Policy.Name, rule.Type, rule.Name, rule.Message)
|
||||
eventInfos = append(eventInfos, e)
|
||||
}
|
||||
|
||||
if !er.IsFailed() {
|
||||
// generate event on policy for success rules
|
||||
logger.V(4).Info("generating event on policy for success rules")
|
||||
e := event.Info{}
|
||||
kind := "ClusterPolicy"
|
||||
if er.PolicyResponse.Policy.Namespace != "" {
|
||||
kind = "Policy"
|
||||
}
|
||||
e.Kind = kind
|
||||
e.Namespace = er.PolicyResponse.Policy.Namespace
|
||||
e.Name = er.PolicyResponse.Policy.Name
|
||||
e.Reason = event.PolicyApplied.String()
|
||||
e.Source = event.PolicyController
|
||||
e.Message = fmt.Sprintf("rules '%v' successfully applied on resource '%s/%s/%s'", er.GetSuccessRules(), er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
|
||||
eventInfos = append(eventInfos, e)
|
||||
}
|
||||
|
||||
if !er.IsSuccessful() {
|
||||
// generate event on policy for failed rules
|
||||
logger.V(4).Info("generating event on policy")
|
||||
e := event.Info{}
|
||||
kind := "ClusterPolicy"
|
||||
if er.PolicyResponse.Policy.Namespace != "" {
|
||||
kind = "Policy"
|
||||
}
|
||||
e.Kind = kind
|
||||
e.Name = er.PolicyResponse.Policy.Name
|
||||
e.Namespace = er.PolicyResponse.Policy.Namespace
|
||||
e.Reason = event.PolicyViolation.String()
|
||||
e.Source = event.PolicyController
|
||||
e.Message = fmt.Sprintf("rules '%v' not satisfied on resource '%s/%s/%s'", er.GetFailedRules(), er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
|
||||
eventInfos = append(eventInfos, e)
|
||||
}
|
||||
return eventInfos
|
||||
}
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ func calculateSummary(results []*report.PolicyReportResult) (summary report.Poli
|
|||
|
||||
func buildPVInfo(er *response.EngineResponse) Info {
|
||||
info := Info{
|
||||
PolicyName: er.PolicyResponse.Policy,
|
||||
PolicyName: er.PolicyResponse.Policy.Name,
|
||||
Namespace: er.PatchedResource.GetNamespace(),
|
||||
Results: []EngineResponseResult{
|
||||
{
|
||||
|
|
|
@ -235,10 +235,8 @@ func validateResponse(t *testing.T, er response.PolicyResponse, expected respons
|
|||
// cant do deepEquals and the stats will be different, or we nil those fields and then do a comparison
|
||||
// forcing only the fields that are specified to be comprared
|
||||
// doing a field by fields comparison will allow us to provied more details logs and granular error reporting
|
||||
// check policy name is same :P
|
||||
if er.Policy != expected.Policy {
|
||||
t.Errorf("Policy name: expected %s, received %s", expected.Policy, er.Policy)
|
||||
}
|
||||
// compare policy spec
|
||||
comparePolicySpec(t, er.Policy, expected.Policy)
|
||||
// compare resource spec
|
||||
compareResourceSpec(t, er.Resource, expected.Resource)
|
||||
// //TODO stats
|
||||
|
@ -260,6 +258,17 @@ func validateResponse(t *testing.T, er response.PolicyResponse, expected respons
|
|||
}
|
||||
}
|
||||
|
||||
func comparePolicySpec(t *testing.T, policy response.PolicySpec, expectedPolicy response.PolicySpec) {
|
||||
// namespace
|
||||
if policy.Namespace != expectedPolicy.Namespace {
|
||||
t.Errorf("namespace: expected %s, received %s", expectedPolicy.Namespace, policy.Namespace)
|
||||
}
|
||||
// name
|
||||
if policy.Name != expectedPolicy.Name {
|
||||
t.Errorf("name: expected %s, received %s", expectedPolicy.Name, policy.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func compareResourceSpec(t *testing.T, resource response.ResourceSpec, expectedResource response.ResourceSpec) {
|
||||
// kind
|
||||
if resource.Kind != expectedResource.Kind {
|
||||
|
|
|
@ -97,7 +97,7 @@ func annotationFromEngineResponses(engineResponses []*response.EngineResponse, l
|
|||
var annotationContent = make(map[string]string)
|
||||
for _, engineResponse := range engineResponses {
|
||||
if !engineResponse.IsSuccessful() {
|
||||
log.V(3).Info("skip building annotation; policy failed to apply", "policy", engineResponse.PolicyResponse.Policy)
|
||||
log.V(3).Info("skip building annotation; policy failed to apply", "policy", engineResponse.PolicyResponse.Policy.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ func annotationFromEngineResponses(engineResponses []*response.EngineResponse, l
|
|||
continue
|
||||
}
|
||||
|
||||
policyName := engineResponse.PolicyResponse.Policy
|
||||
policyName := engineResponse.PolicyResponse.Policy.Name
|
||||
for _, rulePatch := range rulePatches {
|
||||
annotationContent[rulePatch.RuleName+"."+policyName+".kyverno.io"] = operationToPastTense[rulePatch.Op] + " " + rulePatch.Path
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ func newPolicyResponse(policy, rule string, patchesStr []string, success bool) r
|
|||
}
|
||||
|
||||
return response.PolicyResponse{
|
||||
Policy: policy,
|
||||
Policy: response.PolicySpec{Name: policy},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
Name: rule,
|
||||
|
|
|
@ -30,7 +30,7 @@ func isResponseSuccessful(engineReponses []*response.EngineResponse) bool {
|
|||
func toBlockResource(engineReponses []*response.EngineResponse, log logr.Logger) bool {
|
||||
for _, er := range engineReponses {
|
||||
if !er.IsSuccessful() && er.PolicyResponse.ValidationFailureAction == common.Enforce {
|
||||
log.Info("spec.ValidationFailureAction set to enforce blocking resource request", "policy", er.PolicyResponse.Policy)
|
||||
log.Info("spec.ValidationFailureAction set to enforce blocking resource request", "policy", er.PolicyResponse.Policy.Name)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func getEnforceFailureErrorMsg(engineResponses []*response.EngineResponse) strin
|
|||
}
|
||||
resourceName = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
|
||||
|
||||
policyToRule[er.PolicyResponse.Policy] = ruleToReason
|
||||
policyToRule[er.PolicyResponse.Policy.Name] = ruleToReason
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ func getErrorMsg(engineReponses []*response.EngineResponse) string {
|
|||
if !er.IsSuccessful() {
|
||||
// resource in engineReponses is identical as this was called per admission request
|
||||
resourceInfo = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
|
||||
str = append(str, fmt.Sprintf("failed policy %s:", er.PolicyResponse.Policy))
|
||||
str = append(str, fmt.Sprintf("failed policy %s:", er.PolicyResponse.Policy.Name))
|
||||
for _, rule := range er.PolicyResponse.Rules {
|
||||
if !rule.Success {
|
||||
str = append(str, rule.ToString())
|
||||
|
|
|
@ -366,7 +366,7 @@ func (ws *WebhookServer) handleDelete(request *v1beta1.AdmissionRequest) {
|
|||
func (ws *WebhookServer) deleteGR(logger logr.Logger, engineResponse *response.EngineResponse) {
|
||||
logger.V(4).Info("querying all generate requests")
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{
|
||||
"generate.kyverno.io/policy-name": engineResponse.PolicyResponse.Policy,
|
||||
"generate.kyverno.io/policy-name": engineResponse.PolicyResponse.Policy.Name,
|
||||
"generate.kyverno.io/resource-name": engineResponse.PolicyResponse.Resource.Name,
|
||||
"generate.kyverno.io/resource-kind": engineResponse.PolicyResponse.Resource.Kind,
|
||||
"generate.kyverno.io/resource-namespace": engineResponse.PolicyResponse.Resource.Namespace,
|
||||
|
@ -401,7 +401,7 @@ func applyGenerateRequest(gnGenerator generate.GenerateRequests, userRequestInfo
|
|||
|
||||
func transform(userRequestInfo kyverno.RequestInfo, er *response.EngineResponse) kyverno.GenerateRequestSpec {
|
||||
gr := kyverno.GenerateRequestSpec{
|
||||
Policy: er.PolicyResponse.Policy,
|
||||
Policy: er.PolicyResponse.Policy.Name,
|
||||
Resource: kyverno.ResourceSpec{
|
||||
Kind: er.PolicyResponse.Resource.Kind,
|
||||
Namespace: er.PolicyResponse.Resource.Namespace,
|
||||
|
@ -421,7 +421,7 @@ type generateStats struct {
|
|||
}
|
||||
|
||||
func (gs generateStats) PolicyName() string {
|
||||
return gs.resp.PolicyResponse.Policy
|
||||
return gs.resp.PolicyResponse.Policy.Name
|
||||
}
|
||||
|
||||
func (gs generateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
|
||||
|
|
|
@ -180,9 +180,9 @@ type mutateStats struct {
|
|||
|
||||
func (ms mutateStats) PolicyName() string {
|
||||
if ms.namespace == "" {
|
||||
return ms.resp.PolicyResponse.Policy
|
||||
return ms.resp.PolicyResponse.Policy.Name
|
||||
}
|
||||
return ms.namespace + "/" + ms.resp.PolicyResponse.Policy
|
||||
return ms.namespace + "/" + ms.resp.PolicyResponse.Policy.Name
|
||||
}
|
||||
|
||||
func (ms mutateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
|
||||
|
|
|
@ -19,7 +19,7 @@ func Test_GenerateStats(t *testing.T) {
|
|||
generateStats: []*response.EngineResponse{
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy1",
|
||||
Policy: response.PolicySpec{Name: "policy1"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
Name: "rule5",
|
||||
|
@ -40,7 +40,7 @@ func Test_GenerateStats(t *testing.T) {
|
|||
},
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy2",
|
||||
Policy: response.PolicySpec{Name: "policy2"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
Name: "rule5",
|
||||
|
@ -86,7 +86,7 @@ func Test_MutateStats(t *testing.T) {
|
|||
mutateStats: []*response.EngineResponse{
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy1",
|
||||
Policy: response.PolicySpec{Name: "policy1"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
Name: "rule1",
|
||||
|
@ -107,7 +107,7 @@ func Test_MutateStats(t *testing.T) {
|
|||
},
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy2",
|
||||
Policy: response.PolicySpec{Name: "policy2"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
Name: "rule1",
|
||||
|
@ -152,7 +152,7 @@ func Test_ValidateStats(t *testing.T) {
|
|||
validateStats: []*response.EngineResponse{
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy1",
|
||||
Policy: response.PolicySpec{Name: "policy1"},
|
||||
ValidationFailureAction: "enforce",
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
|
@ -174,7 +174,7 @@ func Test_ValidateStats(t *testing.T) {
|
|||
},
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "policy2",
|
||||
Policy: response.PolicySpec{Name: "policy2"},
|
||||
Rules: []response.RuleResponse{
|
||||
{
|
||||
Name: "rule3",
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package webhooks
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
kyvernov1alpha1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/response"
|
||||
"strings"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
)
|
||||
|
@ -15,20 +15,38 @@ func generateEvents(engineResponses []*response.EngineResponse, blocked, onUpdat
|
|||
|
||||
// - Admission-Response is SUCCESS
|
||||
// - Some/All policies failed (policy violations generated)
|
||||
// - report event on resource that failed
|
||||
// - report failure event on policy
|
||||
// - report failure event on resource
|
||||
// - Some/All policies succeeded
|
||||
// - report success event on policy
|
||||
// - report success event on resource
|
||||
|
||||
for _, er := range engineResponses {
|
||||
if er.IsSuccessful() {
|
||||
// do not create event on rules that were successful
|
||||
continue
|
||||
}
|
||||
if !er.IsSuccessful() {
|
||||
// Rules that failed
|
||||
failedRules := er.GetFailedRules()
|
||||
filedRulesStr := strings.Join(failedRules, ";")
|
||||
failedRulesStr := strings.Join(failedRules, ";")
|
||||
|
||||
// Event on the policy
|
||||
kind := "ClusterPolicy"
|
||||
if er.PolicyResponse.Policy.Namespace != "" {
|
||||
kind = "Policy"
|
||||
}
|
||||
pe := event.NewEvent(
|
||||
log,
|
||||
kind,
|
||||
kyvernov1alpha1.SchemeGroupVersion.String(),
|
||||
er.PolicyResponse.Policy.Namespace,
|
||||
er.PolicyResponse.Policy.Name,
|
||||
event.PolicyViolation.String(),
|
||||
event.AdmissionController,
|
||||
event.FPolicyApply,
|
||||
failedRulesStr,
|
||||
er.PolicyResponse.Resource.GetKey(),
|
||||
)
|
||||
|
||||
// Event on the resource
|
||||
// event on resource
|
||||
e := event.NewEvent(
|
||||
re := event.NewEvent(
|
||||
log,
|
||||
er.PolicyResponse.Resource.Kind,
|
||||
er.PolicyResponse.Resource.APIVersion,
|
||||
|
@ -36,12 +54,36 @@ func generateEvents(engineResponses []*response.EngineResponse, blocked, onUpdat
|
|||
er.PolicyResponse.Resource.Name,
|
||||
event.PolicyViolation.String(),
|
||||
event.AdmissionController,
|
||||
event.FResourcePolicyFailed,
|
||||
filedRulesStr,
|
||||
er.PolicyResponse.Policy,
|
||||
event.FResourcePolicyApply,
|
||||
failedRulesStr,
|
||||
er.PolicyResponse.Policy.Name,
|
||||
)
|
||||
events = append(events, pe, re)
|
||||
}
|
||||
|
||||
if !er.IsFailed() {
|
||||
successRules := er.GetSuccessRules()
|
||||
successRulesStr := strings.Join(successRules, ";")
|
||||
|
||||
// Event on the policy
|
||||
kind := "ClusterPolicy"
|
||||
if er.PolicyResponse.Policy.Namespace != "" {
|
||||
kind = "Policy"
|
||||
}
|
||||
e := event.NewEvent(
|
||||
log,
|
||||
kind,
|
||||
kyvernov1alpha1.SchemeGroupVersion.String(),
|
||||
er.PolicyResponse.Policy.Namespace,
|
||||
er.PolicyResponse.Policy.Name,
|
||||
event.PolicyApplied.String(),
|
||||
event.AdmissionController,
|
||||
event.SPolicyApply,
|
||||
successRulesStr,
|
||||
er.PolicyResponse.Resource.GetKey(),
|
||||
)
|
||||
events = append(events, e)
|
||||
}
|
||||
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
|
|
@ -218,9 +218,9 @@ type validateStats struct {
|
|||
|
||||
func (vs validateStats) PolicyName() string {
|
||||
if vs.namespace == "" {
|
||||
return vs.resp.PolicyResponse.Policy
|
||||
return vs.resp.PolicyResponse.Policy.Name
|
||||
}
|
||||
return vs.namespace + "/" + vs.resp.PolicyResponse.Policy
|
||||
return vs.namespace + "/" + vs.resp.PolicyResponse.Policy.Name
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@ expected:
|
|||
mutation:
|
||||
patchedresource: test/output/output_mutate_endpoint.yaml
|
||||
policyresponse:
|
||||
policy: policy-endpoints
|
||||
policy:
|
||||
namespace: ''
|
||||
name: policy-endpoints
|
||||
resource:
|
||||
kind: Endpoints
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,8 @@ expected:
|
|||
mutation:
|
||||
patchedresource: test/output/output_mutate_pod_spec.yaml
|
||||
policyresponse:
|
||||
policy: mutate-pods-spec
|
||||
policy:
|
||||
name: mutate-pods-spec
|
||||
resource:
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
|
|
|
@ -6,7 +6,9 @@ expected:
|
|||
mutation:
|
||||
patchedresource: test/output/output_mutate_validate_qos.yaml
|
||||
policyresponse:
|
||||
policy: policy-qos
|
||||
policy:
|
||||
namespace: ''
|
||||
name: policy-qos
|
||||
resource:
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
|
@ -19,7 +21,9 @@ expected:
|
|||
message: successfully processed strategic merge patch
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: policy-qos
|
||||
policy:
|
||||
namespace: ''
|
||||
name: policy-qos
|
||||
resource:
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
|
|
|
@ -6,7 +6,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: validate-default-proc-mount
|
||||
policy:
|
||||
namespace: ''
|
||||
name: validate-default-proc-mount
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: validate-disallow-default-serviceaccount
|
||||
policy:
|
||||
namespace: ''
|
||||
name: validate-disallow-default-serviceaccount
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: check-probe-exists
|
||||
policy:
|
||||
namespace: ''
|
||||
name: check-probe-exists
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,8 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: validate-selinux-options
|
||||
policy:
|
||||
name: validate-selinux-options
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: validate-volumes-whitelist
|
||||
policy:
|
||||
namespace: ''
|
||||
name: validate-volumes-whitelist
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -9,7 +9,9 @@ expected:
|
|||
kind: NetworkPolicy
|
||||
namespace: devtest
|
||||
policyresponse:
|
||||
policy: add-networkpolicy
|
||||
policy:
|
||||
namespace: ''
|
||||
name: add-networkpolicy
|
||||
resource:
|
||||
kind: Namespace
|
||||
apiVersion: v1
|
||||
|
|
|
@ -9,7 +9,9 @@ expected:
|
|||
kind: ResourceQuota
|
||||
namespace: test-namespace-quota
|
||||
policyresponse:
|
||||
policy: add-ns-quota
|
||||
policy:
|
||||
namespace: ''
|
||||
name: add-ns-quota
|
||||
resource:
|
||||
kind: Namespace
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,9 @@ expected:
|
|||
mutation:
|
||||
patchedresource: test/output/pod-with-emptydir.yaml
|
||||
policyresponse:
|
||||
policy: add-safe-to-evict
|
||||
policy:
|
||||
namespace: ''
|
||||
name: add-safe-to-evict
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,9 @@ expected:
|
|||
mutation:
|
||||
patchedresource: test/output/pod-with-hostpath.yaml
|
||||
policyresponse:
|
||||
policy: add-safe-to-evict
|
||||
policy:
|
||||
namespace: ''
|
||||
name: add-safe-to-evict
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,9 @@ expected:
|
|||
mutation:
|
||||
patchedresource: test/resources/pod-with-default-volume.yaml
|
||||
policyresponse:
|
||||
policy: add-safe-to-evict
|
||||
policy:
|
||||
namespace: ''
|
||||
name: add-safe-to-evict
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: disallow-bind-mounts
|
||||
policy:
|
||||
namespace: ''
|
||||
name: disallow-bind-mounts
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: disallow-bind-mounts
|
||||
policy:
|
||||
namespace: ''
|
||||
name: disallow-bind-mounts
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: disallow-host-network-port
|
||||
policy:
|
||||
namespace: ''
|
||||
name: disallow-host-network-port
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: disallow-host-pid-ipc
|
||||
policy:
|
||||
namespace: ''
|
||||
name: disallow-host-pid-ipc
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: disallow-privileged
|
||||
policy:
|
||||
namespace: ''
|
||||
name: disallow-privileged
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -6,7 +6,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: disallow-sysctls
|
||||
policy:
|
||||
namespace: ''
|
||||
name: disallow-sysctls
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: restrict-automount-sa-token
|
||||
policy:
|
||||
namespace: ''
|
||||
name: restrict-automount-sa-token
|
||||
resource:
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: restrict-ingress-classes
|
||||
policy:
|
||||
namespace: ''
|
||||
name: restrict-ingress-classes
|
||||
resource:
|
||||
kind: Ingress
|
||||
apiVersion: v1
|
||||
|
|
|
@ -5,7 +5,9 @@ input:
|
|||
expected:
|
||||
validation:
|
||||
policyresponse:
|
||||
policy: restrict-ingress-classes
|
||||
policy:
|
||||
namespace: ''
|
||||
name: restrict-ingress-classes
|
||||
resource:
|
||||
kind: Ingress
|
||||
apiVersion: v1
|
||||
|
|
Loading…
Add table
Reference in a new issue