From f3b980bfd3370e5209b2fed2a6a81f92a2739367 Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Wed, 8 Feb 2023 15:53:59 +0100 Subject: [PATCH] Implement MetadataClient (#257) * Implement MetadataClient Signed-off-by: Frank Jogeleit --- Makefile | 8 + cmd/run.go | 17 +- cmd/send.go | 3 +- cmd/send/summary.go | 6 +- cmd/send/violations.go | 6 +- go.mod | 39 ++-- go.sum | 167 +++++------------- pkg/api/server.go | 6 +- pkg/api/v1/handler_test.go | 5 +- pkg/cache/cache.go | 14 +- pkg/cache/memory.go | 50 ++++-- pkg/cache/redis.go | 35 ++-- pkg/config/load_test.go | 3 +- pkg/config/resolver.go | 64 +++++-- pkg/config/resolver_test.go | 21 ++- pkg/config/target_factory.go | 4 +- pkg/config/target_factory_test.go | 6 +- .../v1alpha2/clusterpolicyreport_types.go | 7 +- .../v1alpha2/policyreport_types.go | 7 +- pkg/crd/api/policyreport/v1alpha2/register.go | 3 +- .../client/clientset/versioned/clientset.go | 3 +- .../versioned/fake/clientset_generated.go | 7 +- .../clientset/versioned/fake/register.go | 3 +- .../clientset/versioned/scheme/register.go | 3 +- .../v1alpha2/clusterpolicyreport.go | 5 +- .../v1alpha2/fake/fake_clusterpolicyreport.go | 3 +- .../v1alpha2/fake/fake_policyreport.go | 3 +- .../v1alpha2/fake/fake_policyreport_client.go | 3 +- .../policyreport/v1alpha2/policyreport.go | 5 +- .../v1alpha2/policyreport_client.go | 3 +- .../informers/externalversions/factory.go | 7 +- .../informers/externalversions/generic.go | 3 +- .../internalinterfaces/factory_interfaces.go | 3 +- .../v1alpha2/clusterpolicyreport.go | 9 +- .../policyreport/v1alpha2/policyreport.go | 9 +- .../v1alpha2/clusterpolicyreport.go | 3 +- .../policyreport/v1alpha2/policyreport.go | 3 +- pkg/email/client_test.go | 3 +- pkg/email/summary/fixtures_test.go | 2 +- pkg/email/summary/generator.go | 3 +- pkg/email/summary/generator_test.go | 15 +- pkg/email/summary/reporter_test.go | 5 +- pkg/email/violations/fixtures_test.go | 2 +- pkg/email/violations/generator.go | 3 +- pkg/email/violations/generator_test.go | 15 +- pkg/email/violations/reporter_test.go | 5 +- pkg/fixtures/policy_reports.go | 24 ++- pkg/fixtures/policy_results.go | 15 +- pkg/fixtures/target_results.go | 3 +- pkg/kubernetes/cache.go | 7 + pkg/kubernetes/debouncer.go | 21 +-- pkg/kubernetes/debouncer_test.go | 81 ++++++++- pkg/kubernetes/fixtures_test.go | 15 +- pkg/kubernetes/policy_report_client.go | 99 ++++------- pkg/kubernetes/policy_report_client_test.go | 98 +++++++--- pkg/kubernetes/queue.go | 138 +++++++++++++++ pkg/kubernetes/secrets/client_test.go | 3 +- pkg/listener/fixture_test.go | 3 +- pkg/listener/metrics.go | 2 +- pkg/listener/metrics/cache.go | 85 +++++++++ pkg/listener/metrics/cluster_policy_report.go | 7 +- .../metrics/cluster_policy_report_test.go | 21 +-- .../metrics/cluster_result_detailed.go | 33 ++-- .../metrics/cluster_result_detailed_test.go | 21 +-- pkg/listener/metrics/fixtures_test.go | 3 +- pkg/listener/metrics/model_test.go | 9 + pkg/listener/metrics/policy_report.go | 7 +- pkg/listener/metrics/policy_report_test.go | 19 +- pkg/listener/metrics/result_custom.go | 50 +++--- pkg/listener/metrics/result_custom_test.go | 33 ++-- pkg/listener/metrics/result_detailed.go | 33 ++-- pkg/listener/metrics/result_detailed_test.go | 21 +-- pkg/listener/metrics_test.go | 18 +- pkg/listener/new_result.go | 29 ++- pkg/listener/new_result_test.go | 26 +-- pkg/listener/send_result.go | 4 +- pkg/listener/store.go | 6 +- pkg/listener/store_test.go | 6 +- pkg/report/client.go | 4 +- pkg/report/filter.go | 6 +- pkg/report/filter_test.go | 1 + pkg/report/model.go | 5 +- pkg/report/model_test.go | 3 +- pkg/report/publisher_test.go | 20 +-- pkg/report/store_test.go | 3 +- pkg/sqlite3/store.go | 17 +- pkg/sqlite3/store_test.go | 3 +- pkg/target/client.go | 1 + pkg/target/client_test.go | 3 +- pkg/target/loki/loki.go | 2 +- pkg/validate/validate.go | 1 + pkg/validate/validate_test.go | 1 - 92 files changed, 1031 insertions(+), 578 deletions(-) create mode 100644 pkg/kubernetes/cache.go create mode 100644 pkg/kubernetes/queue.go create mode 100644 pkg/listener/metrics/cache.go diff --git a/Makefile b/Makefile index 1b675cd8..dbeafbb0 100644 --- a/Makefile +++ b/Makefile @@ -39,3 +39,11 @@ docker-push: .PHONY: docker-push-dev docker-push-dev: @docker buildx build --progress plane --platform $(PLATFORMS) --tag $(REPO):dev . --build-arg LD_FLAGS=$(LD_FLAGS) --push + +.PHONY: fmt +fmt: + $(call print-target) + @echo "Running gci" + @go run github.com/daixiang0/gci@v0.9.1 write -s standard -s default -s "prefix(github.com/kyverno/policy-reporter)" . + @echo "Running gofumpt" + @go run mvdan.cc/gofumpt@v0.4.0 -w . diff --git a/cmd/run.go b/cmd/run.go index a572129c..cfccb042 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -5,14 +5,14 @@ import ( "flag" "log" - "github.com/kyverno/policy-reporter/pkg/config" - "github.com/kyverno/policy-reporter/pkg/listener" - "github.com/spf13/cobra" "golang.org/x/sync/errgroup" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "k8s.io/klog" + + "github.com/kyverno/policy-reporter/pkg/config" + "github.com/kyverno/policy-reporter/pkg/listener" ) func newRunCMD() *cobra.Command { @@ -103,13 +103,12 @@ func newRunCMD() *cobra.Command { g.Go(server.Start) - stop := make(chan struct{}) - defer close(stop) + g.Go(func() error { + stop := make(chan struct{}) + defer close(stop) - err = client.Run(stop) - if err != nil { - return err - } + return client.Run(stop) + }) return g.Wait() }, diff --git a/cmd/send.go b/cmd/send.go index 08ab6a85..f78db720 100644 --- a/cmd/send.go +++ b/cmd/send.go @@ -3,8 +3,9 @@ package cmd import ( "flag" - "github.com/kyverno/policy-reporter/cmd/send" "github.com/spf13/cobra" + + "github.com/kyverno/policy-reporter/cmd/send" ) func newSendCMD() *cobra.Command { diff --git a/cmd/send/summary.go b/cmd/send/summary.go index 5b11d2bc..ff00bc50 100644 --- a/cmd/send/summary.go +++ b/cmd/send/summary.go @@ -5,12 +5,12 @@ import ( "strings" "sync" - "github.com/kyverno/policy-reporter/pkg/config" - "github.com/kyverno/policy-reporter/pkg/email/summary" - "github.com/spf13/cobra" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + + "github.com/kyverno/policy-reporter/pkg/config" + "github.com/kyverno/policy-reporter/pkg/email/summary" ) func NewSummaryCMD() *cobra.Command { diff --git a/cmd/send/violations.go b/cmd/send/violations.go index dc13aca6..4c6bcb76 100644 --- a/cmd/send/violations.go +++ b/cmd/send/violations.go @@ -5,12 +5,12 @@ import ( "strings" "sync" - "github.com/kyverno/policy-reporter/pkg/config" - "github.com/kyverno/policy-reporter/pkg/email/violations" - "github.com/spf13/cobra" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + + "github.com/kyverno/policy-reporter/pkg/config" + "github.com/kyverno/policy-reporter/pkg/email/violations" ) func NewViolationsCMD() *cobra.Command { diff --git a/go.mod b/go.mod index e3b2b717..c0546d01 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/kyverno/policy-reporter go 1.19 require ( - github.com/aws/aws-sdk-go v1.44.152 + github.com/aws/aws-sdk-go v1.44.196 github.com/go-redis/redis/v8 v8.11.5 github.com/kyverno/go-wildcard v1.0.5 github.com/mattn/go-sqlite3 v1.14.16 @@ -12,11 +12,11 @@ require ( github.com/prometheus/client_model v0.3.0 github.com/segmentio/fasthash v1.0.3 github.com/spf13/cobra v1.6.1 - github.com/spf13/viper v1.14.0 + github.com/spf13/viper v1.15.0 github.com/xhit/go-simple-mail/v2 v2.13.0 golang.org/x/sync v0.1.0 - k8s.io/apimachinery v0.25.4 - k8s.io/client-go v0.25.4 + k8s.io/apimachinery v0.26.1 + k8s.io/client-go v0.26.1 k8s.io/klog v1.0.0 ) @@ -28,7 +28,7 @@ require ( github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/go-test/deep v1.0.8 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -41,51 +41,48 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/magiconair/properties v1.8.6 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.3.0 // indirect - github.com/onsi/gomega v1.22.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect - golang.org/x/sys v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect golang.org/x/text v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect + k8s.io/klog/v2 v2.90.0 // indirect + k8s.io/utils v0.0.0-20230202215443-34013725500c // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) require ( github.com/go-logr/logr v1.2.3 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/google/gnostic v0.6.9 // indirect github.com/imdario/mergo v0.3.13 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/subosito/gotenv v1.4.1 // indirect + github.com/prometheus/common v0.39.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect golang.org/x/net v0.5.0 // indirect - golang.org/x/oauth2 v0.2.0 // indirect - golang.org/x/term v0.4.0 // indirect - golang.org/x/time v0.2.0 // indirect + golang.org/x/oauth2 v0.4.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/time v0.3.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - k8s.io/api v0.25.4 - k8s.io/kube-openapi v0.0.0-20221202012554-9a5fe2dc74e8 // indirect + k8s.io/api v0.26.1 + k8s.io/kube-openapi v0.0.0-20230202010329-39b3636cbaa3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect ) diff --git a/go.sum b/go.sum index b23c92d2..dd77d688 100644 --- a/go.sum +++ b/go.sum @@ -39,23 +39,14 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aws/aws-sdk-go v1.44.152 h1:L9aaepO8wHB67gwuGD8VgIYH/cmQDxieCt7FeLa0+fI= -github.com/aws/aws-sdk-go v1.44.152/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/aws/aws-sdk-go v1.44.196 h1:e3h9M7fpnRHwHOohYmYjgVbcCBvkxKwZiT7fGrxRn28= +github.com/aws/aws-sdk-go v1.44.196/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -67,6 +58,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -92,32 +84,20 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -206,39 +186,29 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kyverno/go-wildcard v1.0.5 h1:QTgNRRUFOGz96AB8xmI6ErDwDqS9noKzYppvIC05SRE= github.com/kyverno/go-wildcard v1.0.5/go.mod h1:sZkBvzy+au8C1uiqOH+SdN4psOL+0nhfWgsZzzJKwbs= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -246,60 +216,33 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.3.0 h1:kUMoxMoQG3ogk/QWyKh3zibV7BKZ+xBpWil1cTylVqc= -github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= -github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI= -github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= @@ -307,9 +250,6 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= @@ -321,11 +261,10 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= -github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -337,8 +276,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM= github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -358,7 +297,6 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -403,7 +341,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -411,7 +348,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -435,10 +371,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= @@ -452,10 +385,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= -golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -470,12 +401,9 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -484,7 +412,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -497,8 +424,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -506,27 +431,23 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -542,8 +463,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE= -golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -697,24 +618,20 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -729,20 +646,20 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.25.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs= -k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= -k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc= -k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= -k8s.io/client-go v0.25.4 h1:3RNRDffAkNU56M/a7gUfXaEzdhZlYhoW8dgViGy5fn8= -k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= +k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= +k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= +k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20221202012554-9a5fe2dc74e8 h1:9YhSRKN/jnjMMFAoDynjbD4Lt6870TPqD+3hDUwRb1A= -k8s.io/kube-openapi v0.0.0-20221202012554-9a5fe2dc74e8/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/klog/v2 v2.90.0 h1:VkTxIV/FjRXn1fgNNcKGM8cfmL1Z33ZjXRTVxKCoF5M= +k8s.io/klog/v2 v2.90.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230202010329-39b3636cbaa3 h1:vV3ZKAUX0nMjTflyfVea98dTfROpIxDaEsQws0FT2Ts= +k8s.io/kube-openapi v0.0.0-20230202010329-39b3636cbaa3/go.mod h1:/BYxry62FuDzmI+i9B+X2pqfySRmSOW2ARmj5Zbqhj0= +k8s.io/utils v0.0.0-20230202215443-34013725500c h1:YVqDar2X7YiQa/DVAXFMDIfGF8uGrHQemlrwRU5NlVI= +k8s.io/utils v0.0.0-20230202215443-34013725500c/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/pkg/api/server.go b/pkg/api/server.go index 1c867feb..957fb1c3 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -4,12 +4,12 @@ import ( "context" "fmt" "net/http" + pprof "net/http/pprof" + + "github.com/prometheus/client_golang/prometheus/promhttp" v1 "github.com/kyverno/policy-reporter/pkg/api/v1" "github.com/kyverno/policy-reporter/pkg/target" - "github.com/prometheus/client_golang/prometheus/promhttp" - - pprof "net/http/pprof" ) // Server for the Lifecycle and optional HTTP REST API diff --git a/pkg/api/v1/handler_test.go b/pkg/api/v1/handler_test.go index 2d088845..1fff17e5 100644 --- a/pkg/api/v1/handler_test.go +++ b/pkg/api/v1/handler_test.go @@ -7,13 +7,14 @@ import ( "testing" "time" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "github.com/kyverno/policy-reporter/pkg/api/v1" "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/sqlite3" "github.com/kyverno/policy-reporter/pkg/target" "github.com/kyverno/policy-reporter/pkg/target/loki" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var seconds = time.Date(2022, 9, 6, 0, 0, 0, 0, time.UTC).Unix() diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index da5eb872..382da8d1 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -1,6 +1,16 @@ package cache +import "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + type Cache interface { - Has(id string) bool - Add(id string) + RemoveReport(id string) + AddReport(report v1alpha2.ReportInterface) + GetResults(id string) []string +} + +type ItemCache interface { + Cache + AddItem(key string, value interface{}) + GetItem(key string) (interface{}, bool) + RemoveItem(key string) } diff --git a/pkg/cache/memory.go b/pkg/cache/memory.go index 8289db1d..4cb429c0 100644 --- a/pkg/cache/memory.go +++ b/pkg/cache/memory.go @@ -4,24 +4,54 @@ import ( "time" gocache "github.com/patrickmn/go-cache" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) type inMemoryCache struct { cache *gocache.Cache } -func (c *inMemoryCache) Has(id string) bool { - _, ok := c.cache.Get(id) +func (c *inMemoryCache) AddReport(report v1alpha2.ReportInterface) { + list := make([]string, 0, len(report.GetResults())) + for _, result := range report.GetResults() { + list = append(list, result.GetID()) + } - return ok + c.cache.Set(report.GetID(), list, gocache.NoExpiration) } -func (c *inMemoryCache) Add(id string) { - c.cache.SetDefault(id, nil) -} - -func NewInMermoryCache(defaultExpiration, cleanupInterval time.Duration) Cache { - return &inMemoryCache{ - cache: gocache.New(defaultExpiration, cleanupInterval), +func (c *inMemoryCache) RemoveReport(id string) { + val, ok := c.cache.Get(id) + if ok { + // don't remove it directly to prevent sending results from instantly recreated reports + c.cache.Set(id, val, 5*time.Minute) + } +} + +func (c *inMemoryCache) GetResults(id string) []string { + list, ok := c.cache.Get(id) + if !ok { + return make([]string, 0) + } + + return list.([]string) +} + +func (c *inMemoryCache) AddItem(key string, value interface{}) { + c.cache.Set(key, value, gocache.NoExpiration) +} + +func (c *inMemoryCache) RemoveItem(key string) { + c.cache.Delete(key) +} + +func (c *inMemoryCache) GetItem(key string) (interface{}, bool) { + return c.cache.Get(key) +} + +func NewInMermoryCache() ItemCache { + return &inMemoryCache{ + cache: gocache.New(gocache.NoExpiration, 5*time.Minute), } } diff --git a/pkg/cache/redis.go b/pkg/cache/redis.go index 59d7c43b..0cb67209 100644 --- a/pkg/cache/redis.go +++ b/pkg/cache/redis.go @@ -2,11 +2,14 @@ package cache import ( "context" + "encoding/json" "fmt" "log" "time" goredis "github.com/go-redis/redis/v8" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) type redisCache struct { @@ -15,23 +18,31 @@ type redisCache struct { ttl time.Duration } -func (r *redisCache) Add(id string) { - err := r.rdb.Set(context.Background(), r.generateKey(id), true, r.ttl).Err() +func (r *redisCache) AddReport(report v1alpha2.ReportInterface) { + list := make([]string, 0, len(report.GetResults())) + for _, result := range report.GetResults() { + list = append(list, result.GetID()) + } + + value, _ := json.Marshal(list) + + r.rdb.Set(context.Background(), r.generateKey(report.GetID()), string(value), 0) +} + +func (r *redisCache) RemoveReport(id string) { + r.rdb.Del(context.Background(), r.generateKey(id)) +} + +func (r *redisCache) GetResults(id string) []string { + list, err := r.rdb.Get(context.Background(), r.generateKey(id)).Result() + results := make([]string, 0) if err != nil { log.Printf("[ERROR] Failed to set result: %s\n", err) } -} -func (r *redisCache) Has(id string) bool { - _, err := r.rdb.Get(context.Background(), r.generateKey(id)).Result() - if err == goredis.Nil { - return false - } else if err != nil { - log.Printf("[ERROR] Failed to get result: %s\n", err) - return false - } + json.Unmarshal([]byte(list), &results) - return true + return results } func (r *redisCache) generateKey(id string) string { diff --git a/pkg/config/load_test.go b/pkg/config/load_test.go index ab7f0e90..b5586762 100644 --- a/pkg/config/load_test.go +++ b/pkg/config/load_test.go @@ -3,8 +3,9 @@ package config_test import ( "testing" - "github.com/kyverno/policy-reporter/pkg/config" "github.com/spf13/cobra" + + "github.com/kyverno/policy-reporter/pkg/config" ) func createCMD() *cobra.Command { diff --git a/pkg/config/resolver.go b/pkg/config/resolver.go index cbc72066..f3adb355 100644 --- a/pkg/config/resolver.go +++ b/pkg/config/resolver.go @@ -4,8 +4,18 @@ import ( "database/sql" "time" + goredis "github.com/go-redis/redis/v8" + _ "github.com/mattn/go-sqlite3" + mail "github.com/xhit/go-simple-mail/v2" + k8s "k8s.io/client-go/kubernetes" + "k8s.io/client-go/metadata" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/workqueue" + "github.com/kyverno/policy-reporter/pkg/api" "github.com/kyverno/policy-reporter/pkg/cache" + "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" + wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/email" "github.com/kyverno/policy-reporter/pkg/email/summary" "github.com/kyverno/policy-reporter/pkg/email/violations" @@ -18,14 +28,6 @@ import ( "github.com/kyverno/policy-reporter/pkg/sqlite3" "github.com/kyverno/policy-reporter/pkg/target" "github.com/kyverno/policy-reporter/pkg/validate" - mail "github.com/xhit/go-simple-mail/v2" - - goredis "github.com/go-redis/redis/v8" - "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" - wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" - _ "github.com/mattn/go-sqlite3" - k8s "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" ) // Resolver manages dependencies @@ -39,6 +41,7 @@ type Resolver struct { leaderElector *leaderelection.Client targetClients []target.Client resultCache cache.Cache + cache cache.ItemCache targetsCreated bool } @@ -105,6 +108,21 @@ func (r *Resolver) EventPublisher() report.EventPublisher { return r.publisher } +// EventPublisher resolver method +func (r *Resolver) Queue() (*kubernetes.Queue, error) { + client, err := r.CRDClient() + if err != nil { + return nil, err + } + + return kubernetes.NewQueue( + r.InMemoryCache(), + kubernetes.NewDebouncer(1*time.Minute, r.EventPublisher()), + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "report-queue"), + client, + ), nil +} + // RegisterSendResultListener resolver method func (r *Resolver) RegisterSendResultListener() { targets := r.TargetClients() @@ -223,6 +241,15 @@ func (r *Resolver) CRDClient() (wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Interface return client.Wgpolicyk8sV1alpha2(), nil } +func (r *Resolver) CRDMetadataClient() (metadata.Interface, error) { + client, err := metadata.NewForConfig(r.k8sConfig) + if err != nil { + return nil, err + } + + return client, nil +} + func (r *Resolver) SummaryGenerator() (*summary.Generator, error) { client, err := r.CRDClient() if err != nil { @@ -285,12 +312,17 @@ func (r *Resolver) PolicyReportClient() (report.PolicyReportClient, error) { return r.policyReportClient, nil } - client, err := versioned.NewForConfig(r.k8sConfig) + client, err := r.CRDMetadataClient() if err != nil { return nil, err } - r.policyReportClient = kubernetes.NewPolicyReportClient(client, r.ReportFilter(), r.EventPublisher()) + queue, err := r.Queue() + if err != nil { + return nil, err + } + + r.policyReportClient = kubernetes.NewPolicyReportClient(client, r.ReportFilter(), queue) return r.policyReportClient, nil } @@ -302,6 +334,16 @@ func (r *Resolver) ReportFilter() *report.Filter { ) } +func (r *Resolver) InMemoryCache() cache.ItemCache { + if r.cache != nil { + return r.cache + } + + r.cache = cache.NewInMermoryCache() + + return r.cache +} + // ResultCache resolver method func (r *Resolver) ResultCache() cache.Cache { if r.resultCache != nil { @@ -320,7 +362,7 @@ func (r *Resolver) ResultCache() cache.Cache { 2*time.Hour, ) } else { - r.resultCache = cache.NewInMermoryCache(time.Minute*150, time.Minute*15) + r.resultCache = cache.NewInMermoryCache() } return r.resultCache diff --git a/pkg/config/resolver_test.go b/pkg/config/resolver_test.go index eec7121a..9904d73c 100644 --- a/pkg/config/resolver_test.go +++ b/pkg/config/resolver_test.go @@ -3,9 +3,10 @@ package config_test import ( "testing" + "k8s.io/client-go/rest" + "github.com/kyverno/policy-reporter/pkg/config" "github.com/kyverno/policy-reporter/pkg/report" - "k8s.io/client-go/rest" ) var testConfig = &config.Config{ @@ -135,7 +136,7 @@ func Test_ResolveHasTargets(t *testing.T) { } func Test_ResolveSkipExistingOnStartup(t *testing.T) { - var testConfig = &config.Config{ + testConfig := &config.Config{ Loki: config.Loki{ Host: "http://localhost:3100", SkipExisting: true, @@ -238,7 +239,7 @@ func Test_ResolveCache(t *testing.T) { }) t.Run("Redis", func(t *testing.T) { - var redisConfig = &config.Config{ + redisConfig := &config.Config{ Redis: config.Redis{ Enabled: true, Address: "localhost:6379", @@ -268,6 +269,20 @@ func Test_ResolveMapper(t *testing.T) { } } +func Test_ResolveInMemoryCache(t *testing.T) { + resolver := config.NewResolver(testConfig, &rest.Config{}) + + cache1 := resolver.InMemoryCache() + if cache1 == nil { + t.Error("Error: Should return InMemoryCache") + } + + cache2 := resolver.InMemoryCache() + if cache1 != cache2 { + t.Error("A second call resolver.InMemoryCache() should return the cached first cache") + } +} + func Test_ResolveReportFilter(t *testing.T) { resolver := config.NewResolver(testConfig, &rest.Config{}) diff --git a/pkg/config/target_factory.go b/pkg/config/target_factory.go index cb76d8ea..fe43f726 100644 --- a/pkg/config/target_factory.go +++ b/pkg/config/target_factory.go @@ -5,6 +5,8 @@ import ( "fmt" "log" + _ "github.com/mattn/go-sqlite3" + "github.com/kyverno/policy-reporter/pkg/helper" "github.com/kyverno/policy-reporter/pkg/kubernetes/secrets" "github.com/kyverno/policy-reporter/pkg/report" @@ -19,8 +21,6 @@ import ( "github.com/kyverno/policy-reporter/pkg/target/teams" "github.com/kyverno/policy-reporter/pkg/target/ui" "github.com/kyverno/policy-reporter/pkg/target/webhook" - - _ "github.com/mattn/go-sqlite3" ) // TargetFactory manages target creation diff --git a/pkg/config/target_factory_test.go b/pkg/config/target_factory_test.go index 52fffe6e..4a76ce60 100644 --- a/pkg/config/target_factory_test.go +++ b/pkg/config/target_factory_test.go @@ -4,12 +4,13 @@ import ( "reflect" "testing" - "github.com/kyverno/policy-reporter/pkg/config" - "github.com/kyverno/policy-reporter/pkg/kubernetes/secrets" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" v1 "k8s.io/client-go/kubernetes/typed/core/v1" + + "github.com/kyverno/policy-reporter/pkg/config" + "github.com/kyverno/policy-reporter/pkg/kubernetes/secrets" ) const secretName = "secret-values" @@ -40,7 +41,6 @@ func Test_ResolveTarget(t *testing.T) { if len(clients) != 2 { t.Errorf("Expected 2 Client, got %d clients", len(clients)) } - }) t.Run("Elasticsearch", func(t *testing.T) { clients := factory.ElasticsearchClients(testConfig.Elasticsearch) diff --git a/pkg/crd/api/policyreport/v1alpha2/clusterpolicyreport_types.go b/pkg/crd/api/policyreport/v1alpha2/clusterpolicyreport_types.go index 4c3fc686..ce195590 100755 --- a/pkg/crd/api/policyreport/v1alpha2/clusterpolicyreport_types.go +++ b/pkg/crd/api/policyreport/v1alpha2/clusterpolicyreport_types.go @@ -19,10 +19,11 @@ package v1alpha2 import ( "strconv" - "github.com/kyverno/policy-reporter/pkg/helper" "github.com/segmentio/fasthash/fnv1a" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyverno/policy-reporter/pkg/helper" ) // +genclient @@ -91,7 +92,7 @@ func (r *ClusterPolicyReport) GetID() string { } func (r *ClusterPolicyReport) GetKinds() []string { - var list = make([]string, 0) + list := make([]string, 0) for _, k := range r.Results { if !k.HasResource() { continue @@ -110,7 +111,7 @@ func (r *ClusterPolicyReport) GetKinds() []string { } func (r *ClusterPolicyReport) GetSeverities() []string { - var list = make([]string, 0) + list := make([]string, 0) for _, k := range r.Results { if k.Severity == "" || helper.Contains(string(k.Severity), list) { diff --git a/pkg/crd/api/policyreport/v1alpha2/policyreport_types.go b/pkg/crd/api/policyreport/v1alpha2/policyreport_types.go index 0efe6304..4441ec70 100644 --- a/pkg/crd/api/policyreport/v1alpha2/policyreport_types.go +++ b/pkg/crd/api/policyreport/v1alpha2/policyreport_types.go @@ -16,10 +16,11 @@ package v1alpha2 import ( "strconv" - "github.com/kyverno/policy-reporter/pkg/helper" "github.com/segmentio/fasthash/fnv1a" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyverno/policy-reporter/pkg/helper" ) // +genclient @@ -80,7 +81,7 @@ func (r *PolicyReport) GetSource() string { } func (r *PolicyReport) GetKinds() []string { - var list = make([]string, 0) + list := make([]string, 0) for _, k := range r.Results { if !k.HasResource() { continue @@ -99,7 +100,7 @@ func (r *PolicyReport) GetKinds() []string { } func (r *PolicyReport) GetSeverities() []string { - var list = make([]string, 0) + list := make([]string, 0) for _, k := range r.Results { if k.Severity == "" || helper.Contains(string(k.Severity), list) { diff --git a/pkg/crd/api/policyreport/v1alpha2/register.go b/pkg/crd/api/policyreport/v1alpha2/register.go index 55676f78..9db96137 100755 --- a/pkg/crd/api/policyreport/v1alpha2/register.go +++ b/pkg/crd/api/policyreport/v1alpha2/register.go @@ -17,10 +17,11 @@ limitations under the License. package v1alpha2 import ( - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport" ) // SchemeGroupVersion is group version used to register these objects diff --git a/pkg/crd/client/clientset/versioned/clientset.go b/pkg/crd/client/clientset/versioned/clientset.go index d9051a2f..b2459916 100644 --- a/pkg/crd/client/clientset/versioned/clientset.go +++ b/pkg/crd/client/clientset/versioned/clientset.go @@ -22,10 +22,11 @@ import ( "fmt" "net/http" - wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" + + wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" ) type Interface interface { diff --git a/pkg/crd/client/clientset/versioned/fake/clientset_generated.go b/pkg/crd/client/clientset/versioned/fake/clientset_generated.go index e2400fab..7125d373 100644 --- a/pkg/crd/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/crd/client/clientset/versioned/fake/clientset_generated.go @@ -19,14 +19,15 @@ limitations under the License. package fake import ( - clientset "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" - wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" - fakewgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" fakediscovery "k8s.io/client-go/discovery/fake" "k8s.io/client-go/testing" + + clientset "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" + wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" + fakewgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake" ) // NewSimpleClientset returns a clientset that will respond with the provided objects. diff --git a/pkg/crd/client/clientset/versioned/fake/register.go b/pkg/crd/client/clientset/versioned/fake/register.go index bd4634d8..1d513143 100644 --- a/pkg/crd/client/clientset/versioned/fake/register.go +++ b/pkg/crd/client/clientset/versioned/fake/register.go @@ -19,12 +19,13 @@ limitations under the License. package fake import ( - wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + + wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) var scheme = runtime.NewScheme() diff --git a/pkg/crd/client/clientset/versioned/scheme/register.go b/pkg/crd/client/clientset/versioned/scheme/register.go index b0f95397..2bf20368 100644 --- a/pkg/crd/client/clientset/versioned/scheme/register.go +++ b/pkg/crd/client/clientset/versioned/scheme/register.go @@ -19,12 +19,13 @@ limitations under the License. package scheme import ( - wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + + wgpolicyk8sv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) var Scheme = runtime.NewScheme() diff --git a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/clusterpolicyreport.go b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/clusterpolicyreport.go index 306004b7..82e305ad 100644 --- a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/clusterpolicyreport.go +++ b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/clusterpolicyreport.go @@ -22,12 +22,13 @@ import ( "context" "time" - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - scheme "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rest "k8s.io/client-go/rest" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + scheme "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/scheme" ) // ClusterPolicyReportsGetter has a method to return a ClusterPolicyReportInterface. diff --git a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_clusterpolicyreport.go b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_clusterpolicyreport.go index 2e6fca5b..20c83699 100644 --- a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_clusterpolicyreport.go +++ b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_clusterpolicyreport.go @@ -21,13 +21,14 @@ package fake import ( "context" - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) // FakeClusterPolicyReports implements ClusterPolicyReportInterface diff --git a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport.go b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport.go index 2917e355..00905c0e 100644 --- a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport.go +++ b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport.go @@ -21,13 +21,14 @@ package fake import ( "context" - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) // FakePolicyReports implements PolicyReportInterface diff --git a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport_client.go b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport_client.go index daaca53c..6bed4aae 100644 --- a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport_client.go +++ b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/fake/fake_policyreport_client.go @@ -19,9 +19,10 @@ limitations under the License. package fake import ( - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" ) type FakeWgpolicyk8sV1alpha2 struct { diff --git a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport.go b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport.go index 5be7c793..07a1a05b 100644 --- a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport.go +++ b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport.go @@ -22,12 +22,13 @@ import ( "context" "time" - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - scheme "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rest "k8s.io/client-go/rest" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + scheme "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/scheme" ) // PolicyReportsGetter has a method to return a PolicyReportInterface. diff --git a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport_client.go b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport_client.go index 0b4a6418..40072e8a 100644 --- a/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport_client.go +++ b/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2/policyreport_client.go @@ -21,9 +21,10 @@ package v1alpha2 import ( "net/http" + rest "k8s.io/client-go/rest" + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/scheme" - rest "k8s.io/client-go/rest" ) type Wgpolicyk8sV1alpha2Interface interface { diff --git a/pkg/crd/client/informers/externalversions/factory.go b/pkg/crd/client/informers/externalversions/factory.go index c49cf0ea..40f0b932 100644 --- a/pkg/crd/client/informers/externalversions/factory.go +++ b/pkg/crd/client/informers/externalversions/factory.go @@ -23,13 +23,14 @@ import ( sync "sync" time "time" - versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" - internalinterfaces "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/internalinterfaces" - policyreport "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/policyreport" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" + + versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" + internalinterfaces "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/internalinterfaces" + policyreport "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/policyreport" ) // SharedInformerOption defines the functional option type for SharedInformerFactory. diff --git a/pkg/crd/client/informers/externalversions/generic.go b/pkg/crd/client/informers/externalversions/generic.go index fe28164f..ae8fc7a7 100644 --- a/pkg/crd/client/informers/externalversions/generic.go +++ b/pkg/crd/client/informers/externalversions/generic.go @@ -21,9 +21,10 @@ package externalversions import ( "fmt" - policyreportv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" + + policyreportv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) // GenericInformer is type of SharedIndexInformer which will locate and delegate to other diff --git a/pkg/crd/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/crd/client/informers/externalversions/internalinterfaces/factory_interfaces.go index 7e75e09f..caa38720 100644 --- a/pkg/crd/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/crd/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -21,10 +21,11 @@ package internalinterfaces import ( time "time" - versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" cache "k8s.io/client-go/tools/cache" + + versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" ) // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. diff --git a/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/clusterpolicyreport.go b/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/clusterpolicyreport.go index 8ec14a59..49e23690 100644 --- a/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/clusterpolicyreport.go +++ b/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/clusterpolicyreport.go @@ -22,14 +22,15 @@ import ( "context" time "time" - policyreportv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" - internalinterfaces "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/internalinterfaces" - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/listers/policyreport/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" + + policyreportv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" + internalinterfaces "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/internalinterfaces" + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/listers/policyreport/v1alpha2" ) // ClusterPolicyReportInformer provides access to a shared informer and lister for diff --git a/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/policyreport.go b/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/policyreport.go index 902f3d17..91ee5d34 100644 --- a/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/policyreport.go +++ b/pkg/crd/client/informers/externalversions/policyreport/v1alpha2/policyreport.go @@ -22,14 +22,15 @@ import ( "context" time "time" - policyreportv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" - internalinterfaces "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/internalinterfaces" - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/listers/policyreport/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" + + policyreportv1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + versioned "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" + internalinterfaces "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/internalinterfaces" + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/client/listers/policyreport/v1alpha2" ) // PolicyReportInformer provides access to a shared informer and lister for diff --git a/pkg/crd/client/listers/policyreport/v1alpha2/clusterpolicyreport.go b/pkg/crd/client/listers/policyreport/v1alpha2/clusterpolicyreport.go index 3673c333..fddfc7e5 100644 --- a/pkg/crd/client/listers/policyreport/v1alpha2/clusterpolicyreport.go +++ b/pkg/crd/client/listers/policyreport/v1alpha2/clusterpolicyreport.go @@ -19,10 +19,11 @@ limitations under the License. package v1alpha2 import ( - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) // ClusterPolicyReportLister helps list ClusterPolicyReports. diff --git a/pkg/crd/client/listers/policyreport/v1alpha2/policyreport.go b/pkg/crd/client/listers/policyreport/v1alpha2/policyreport.go index 71ad9e39..889b86b8 100644 --- a/pkg/crd/client/listers/policyreport/v1alpha2/policyreport.go +++ b/pkg/crd/client/listers/policyreport/v1alpha2/policyreport.go @@ -19,10 +19,11 @@ limitations under the License. package v1alpha2 import ( - v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" + + v1alpha2 "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) // PolicyReportLister helps list PolicyReports. diff --git a/pkg/email/client_test.go b/pkg/email/client_test.go index 3a7eac3e..2a577f78 100644 --- a/pkg/email/client_test.go +++ b/pkg/email/client_test.go @@ -3,8 +3,9 @@ package email_test import ( "testing" - "github.com/kyverno/policy-reporter/pkg/email" mail "github.com/xhit/go-simple-mail/v2" + + "github.com/kyverno/policy-reporter/pkg/email" ) func Test_EncryptionFromString(t *testing.T) { diff --git a/pkg/email/summary/fixtures_test.go b/pkg/email/summary/fixtures_test.go index 331eff02..f4adca8a 100644 --- a/pkg/email/summary/fixtures_test.go +++ b/pkg/email/summary/fixtures_test.go @@ -9,7 +9,7 @@ import ( var filter = email.NewFilter(validate.RuleSets{}, validate.RuleSets{}) -func NewFakeCilent() (v1alpha2client.Wgpolicyk8sV1alpha2Interface, v1alpha2client.PolicyReportInterface, v1alpha2client.ClusterPolicyReportInterface) { +func NewFakeClient() (v1alpha2client.Wgpolicyk8sV1alpha2Interface, v1alpha2client.PolicyReportInterface, v1alpha2client.ClusterPolicyReportInterface) { client := fake.NewSimpleClientset().Wgpolicyk8sV1alpha2() return client, client.PolicyReports("test"), client.ClusterPolicyReports() diff --git a/pkg/email/summary/generator.go b/pkg/email/summary/generator.go index 3e71f008..6b7761d7 100644 --- a/pkg/email/summary/generator.go +++ b/pkg/email/summary/generator.go @@ -5,10 +5,11 @@ import ( "log" "sync" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" api "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/email" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type Generator struct { diff --git a/pkg/email/summary/generator_test.go b/pkg/email/summary/generator_test.go index bb8d1151..e473b42f 100644 --- a/pkg/email/summary/generator_test.go +++ b/pkg/email/summary/generator_test.go @@ -4,17 +4,18 @@ import ( "context" "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/email" "github.com/kyverno/policy-reporter/pkg/email/summary" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/validate" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_GenerateDataWithSingleSource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = cClient.Create(ctx, fixtures.ClusterPolicyReport, v1.CreateOptions{}) @@ -45,7 +46,7 @@ func Test_GenerateDataWithSingleSource(t *testing.T) { func Test_GenerateDataWithMultipleSource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -70,7 +71,7 @@ func Test_GenerateDataWithMultipleSource(t *testing.T) { func Test_GenerateDataWithSourceFilter(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -95,7 +96,7 @@ func Test_GenerateDataWithSourceFilter(t *testing.T) { func Test_FilterSourcesBySource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -121,7 +122,7 @@ func Test_FilterSourcesBySource(t *testing.T) { func Test_FilterSourcesByNamespace(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -152,7 +153,7 @@ func Test_FilterSourcesByNamespace(t *testing.T) { func Test_RemoveEmptySource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) diff --git a/pkg/email/summary/reporter_test.go b/pkg/email/summary/reporter_test.go index afaa5c65..8b07251e 100644 --- a/pkg/email/summary/reporter_test.go +++ b/pkg/email/summary/reporter_test.go @@ -6,15 +6,16 @@ import ( "os" "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/email/summary" "github.com/kyverno/policy-reporter/pkg/fixtures" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_CreateReport(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) diff --git a/pkg/email/violations/fixtures_test.go b/pkg/email/violations/fixtures_test.go index 1d0f29ec..fe9d0f5a 100644 --- a/pkg/email/violations/fixtures_test.go +++ b/pkg/email/violations/fixtures_test.go @@ -9,7 +9,7 @@ import ( var filter = email.NewFilter(validate.RuleSets{}, validate.RuleSets{}) -func NewFakeCilent() (v1alpha2client.Wgpolicyk8sV1alpha2Interface, v1alpha2client.PolicyReportInterface, v1alpha2client.ClusterPolicyReportInterface) { +func NewFakeClient() (v1alpha2client.Wgpolicyk8sV1alpha2Interface, v1alpha2client.PolicyReportInterface, v1alpha2client.ClusterPolicyReportInterface) { client := fake.NewSimpleClientset().Wgpolicyk8sV1alpha2() return client, client.PolicyReports("test"), client.ClusterPolicyReports() diff --git a/pkg/email/violations/generator.go b/pkg/email/violations/generator.go index 9a92727d..23b3e585 100644 --- a/pkg/email/violations/generator.go +++ b/pkg/email/violations/generator.go @@ -5,10 +5,11 @@ import ( "log" "sync" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" api "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/email" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type Generator struct { diff --git a/pkg/email/violations/generator_test.go b/pkg/email/violations/generator_test.go index a1ed92d3..519b92a7 100644 --- a/pkg/email/violations/generator_test.go +++ b/pkg/email/violations/generator_test.go @@ -4,17 +4,18 @@ import ( "context" "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/email" "github.com/kyverno/policy-reporter/pkg/email/violations" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/validate" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_GenerateDataWithSingleSource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = cClient.Create(ctx, fixtures.PassClusterPolicyReport, v1.CreateOptions{}) @@ -67,7 +68,7 @@ func Test_GenerateDataWithSingleSource(t *testing.T) { func Test_GenerateDataWithMultipleSource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -94,7 +95,7 @@ func Test_GenerateDataWithMultipleSource(t *testing.T) { func Test_GenerateDataWithSourceFilter(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -119,7 +120,7 @@ func Test_GenerateDataWithSourceFilter(t *testing.T) { func Test_FilterSourcesBySource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -145,7 +146,7 @@ func Test_FilterSourcesBySource(t *testing.T) { func Test_FilterSourcesByNamespace(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) @@ -176,7 +177,7 @@ func Test_FilterSourcesByNamespace(t *testing.T) { func Test_RemoveEmptySource(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) diff --git a/pkg/email/violations/reporter_test.go b/pkg/email/violations/reporter_test.go index c1eb8e63..ba17a238 100644 --- a/pkg/email/violations/reporter_test.go +++ b/pkg/email/violations/reporter_test.go @@ -6,15 +6,16 @@ import ( "os" "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/email/violations" "github.com/kyverno/policy-reporter/pkg/fixtures" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_CreateReport(t *testing.T) { ctx := context.Background() - client, pClient, cClient := NewFakeCilent() + client, pClient, cClient := NewFakeClient() _, _ = pClient.Create(ctx, fixtures.DefaultPolicyReport, v1.CreateOptions{}) _, _ = pClient.Create(ctx, fixtures.EmptyPolicyReport, v1.CreateOptions{}) diff --git a/pkg/fixtures/policy_reports.go b/pkg/fixtures/policy_reports.go index f82dff08..0e2d1441 100644 --- a/pkg/fixtures/policy_reports.go +++ b/pkg/fixtures/policy_reports.go @@ -1,11 +1,23 @@ package fixtures import ( - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) +var DefaultMeta = &v1.PartialObjectMetadata{ + ObjectMeta: v1.ObjectMeta{ + Name: "policy-report", + Namespace: "test", + }, + TypeMeta: v1.TypeMeta{ + Kind: "PolicyReport", + APIVersion: "wgpolicyk8s.io/v1alpha2", + }, +} + var DefaultPolicyReport = &v1alpha2.PolicyReport{ ObjectMeta: v1.ObjectMeta{ Name: "policy-report", @@ -177,6 +189,16 @@ var EnforceReport = &v1alpha2.PolicyReport{ }, } +var DefaultClusterMeta = &v1.PartialObjectMetadata{ + ObjectMeta: v1.ObjectMeta{ + Name: "cluster-policy-report", + }, + TypeMeta: v1.TypeMeta{ + Kind: "ClusterPolicyReport", + APIVersion: "wgpolicyk8s.io/v1alpha2", + }, +} + var ClusterPolicyReport = &v1alpha2.ClusterPolicyReport{ ObjectMeta: v1.ObjectMeta{ Name: "cluster-policy-report", diff --git a/pkg/fixtures/policy_results.go b/pkg/fixtures/policy_results.go index 5f1572ef..889a9b84 100644 --- a/pkg/fixtures/policy_results.go +++ b/pkg/fixtures/policy_results.go @@ -1,8 +1,9 @@ package fixtures import ( - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" corev1 "k8s.io/api/core/v1" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) var PassResult = v1alpha2.PolicyReportResult{ @@ -44,6 +45,18 @@ var PassPodResult = v1alpha2.PolicyReportResult{ }}, } +var TrivyResult = v1alpha2.PolicyReportResult{ + ID: "124", + Message: "validation error", + Policy: "policy", + Rule: "rule", + Priority: v1alpha2.WarningPriority, + Result: v1alpha2.StatusFail, + Category: "Best Practices", + Scored: true, + Source: "Trivy", +} + var FailResult = v1alpha2.PolicyReportResult{ ID: "123", Message: "validation error: requests and limits required. Rule autogen-check-for-requests-and-limits failed at path /spec/template/spec/containers/0/resources/requests/", diff --git a/pkg/fixtures/target_results.go b/pkg/fixtures/target_results.go index a74f19bc..06fbaefc 100644 --- a/pkg/fixtures/target_results.go +++ b/pkg/fixtures/target_results.go @@ -3,9 +3,10 @@ package fixtures import ( "time" - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) var seconds = time.Date(2021, time.February, 23, 15, 10, 0, 0, time.UTC).Unix() diff --git a/pkg/kubernetes/cache.go b/pkg/kubernetes/cache.go new file mode 100644 index 00000000..b9e48212 --- /dev/null +++ b/pkg/kubernetes/cache.go @@ -0,0 +1,7 @@ +package kubernetes + +type Cache interface { + AddItem(string, interface{}) + GetItem(string) (interface{}, bool) + RemoveItem(string) +} diff --git a/pkg/kubernetes/debouncer.go b/pkg/kubernetes/debouncer.go index 20cc0a75..6b196818 100644 --- a/pkg/kubernetes/debouncer.go +++ b/pkg/kubernetes/debouncer.go @@ -19,30 +19,30 @@ type debouncer struct { } func (d *debouncer) Add(event report.LifecycleEvent) { - cached, ok := d.events[event.NewPolicyReport.GetID()] + _, ok := d.events[event.PolicyReport.GetID()] if event.Type != report.Updated && ok { d.mutx.Lock() - delete(d.events, event.NewPolicyReport.GetID()) + delete(d.events, event.PolicyReport.GetID()) d.mutx.Unlock() } - if event.Type == report.Added || event.Type == report.Deleted { + if event.Type != report.Updated { d.publisher.Publish(event) return } - if len(event.NewPolicyReport.GetResults()) == 0 && !ok { + if len(event.PolicyReport.GetResults()) == 0 && !ok { d.mutx.Lock() - d.events[event.NewPolicyReport.GetID()] = event + d.events[event.PolicyReport.GetID()] = event d.mutx.Unlock() go func() { time.Sleep(d.waitDuration) d.mutx.Lock() - if event, ok := d.events[event.NewPolicyReport.GetID()]; ok { + if event, ok := d.events[event.PolicyReport.GetID()]; ok { d.publisher.Publish(event) - delete(d.events, event.NewPolicyReport.GetID()) + delete(d.events, event.PolicyReport.GetID()) } d.mutx.Unlock() }() @@ -50,13 +50,10 @@ func (d *debouncer) Add(event report.LifecycleEvent) { return } - if ok { + if len(event.PolicyReport.GetResults()) > 0 && ok { d.mutx.Lock() - event.OldPolicyReport = cached.OldPolicyReport - d.events[event.NewPolicyReport.GetID()] = event + delete(d.events, event.PolicyReport.GetID()) d.mutx.Unlock() - - return } d.publisher.Publish(event) diff --git a/pkg/kubernetes/debouncer_test.go b/pkg/kubernetes/debouncer_test.go index e0fe5a19..26faa0f0 100644 --- a/pkg/kubernetes/debouncer_test.go +++ b/pkg/kubernetes/debouncer_test.go @@ -25,20 +25,89 @@ func Test_Debouncer(t *testing.T) { debouncer := kubernetes.NewDebouncer(200*time.Millisecond, publisher) debouncer.Add(report.LifecycleEvent{ - Type: report.Added, - NewPolicyReport: fixtures.DefaultPolicyReport, + Type: report.Added, + PolicyReport: fixtures.DefaultPolicyReport, }) debouncer.Add(report.LifecycleEvent{ - Type: report.Updated, - NewPolicyReport: fixtures.MinPolicyReport, + Type: report.Updated, + PolicyReport: fixtures.MinPolicyReport, }) time.Sleep(10 * time.Millisecond) debouncer.Add(report.LifecycleEvent{ - Type: report.Updated, - NewPolicyReport: fixtures.DefaultPolicyReport, + Type: report.Updated, + PolicyReport: fixtures.DefaultPolicyReport, + }) + + wg.Wait() + + if counter != 2 { + t.Error("Expected to skip the empty modify event") + } + }) + + t.Run("Execute Empty Updates after waiting time", func(t *testing.T) { + counter := 0 + wg := sync.WaitGroup{} + wg.Add(2) + + publisher := report.NewEventPublisher() + publisher.RegisterListener("test", func(event report.LifecycleEvent) { + counter++ + wg.Done() + }) + + debouncer := kubernetes.NewDebouncer(10*time.Millisecond, publisher) + + debouncer.Add(report.LifecycleEvent{ + Type: report.Added, + PolicyReport: fixtures.DefaultPolicyReport, + }) + + debouncer.Add(report.LifecycleEvent{ + Type: report.Updated, + PolicyReport: fixtures.MinPolicyReport, + }) + + time.Sleep(5 * time.Millisecond) + + wg.Wait() + + if counter != 2 { + t.Error("Expected to execute empty update event after wait time") + } + }) + + t.Run("Skip Empty Update when delete event follows directly", func(t *testing.T) { + counter := 0 + wg := sync.WaitGroup{} + wg.Add(2) + + publisher := report.NewEventPublisher() + publisher.RegisterListener("test", func(event report.LifecycleEvent) { + counter++ + wg.Done() + }) + + debouncer := kubernetes.NewDebouncer(200*time.Millisecond, publisher) + + debouncer.Add(report.LifecycleEvent{ + Type: report.Added, + PolicyReport: fixtures.DefaultPolicyReport, + }) + + debouncer.Add(report.LifecycleEvent{ + Type: report.Updated, + PolicyReport: fixtures.MinPolicyReport, + }) + + time.Sleep(10 * time.Millisecond) + + debouncer.Add(report.LifecycleEvent{ + Type: report.Deleted, + PolicyReport: fixtures.DefaultPolicyReport, }) wg.Wait() diff --git a/pkg/kubernetes/fixtures_test.go b/pkg/kubernetes/fixtures_test.go index 6d417bf4..9c65d823 100644 --- a/pkg/kubernetes/fixtures_test.go +++ b/pkg/kubernetes/fixtures_test.go @@ -3,13 +3,24 @@ package kubernetes_test import ( "sync" - "github.com/kyverno/policy-reporter/pkg/report" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metafake "k8s.io/client-go/metadata/fake" + pr "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/fake" v1alpha2client "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) -func NewFakeCilent() (*fake.Clientset, v1alpha2client.PolicyReportInterface, v1alpha2client.ClusterPolicyReportInterface) { +func NewFakeMetaClient() (*metafake.FakeMetadataClient, metafake.MetadataClient, metafake.MetadataClient) { + schema := metafake.NewTestScheme() + metav1.AddMetaToScheme(schema) + + client := metafake.NewSimpleMetadataClient(schema) + return client, client.Resource(pr.SchemeGroupVersion.WithResource("policyreports")).Namespace("test").(metafake.MetadataClient), client.Resource(pr.SchemeGroupVersion.WithResource("clusterpolicyreports")).(metafake.MetadataClient) +} + +func NewFakeClient() (*fake.Clientset, v1alpha2client.PolicyReportInterface, v1alpha2client.ClusterPolicyReportInterface) { client := fake.NewSimpleClientset() return client, client.Wgpolicyk8sV1alpha2().PolicyReports("test"), client.Wgpolicyk8sV1alpha2().ClusterPolicyReports() diff --git a/pkg/kubernetes/policy_report_client.go b/pkg/kubernetes/policy_report_client.go index d35ff3e2..c1f8c858 100644 --- a/pkg/kubernetes/policy_report_client.go +++ b/pkg/kubernetes/policy_report_client.go @@ -5,19 +5,22 @@ import ( "sync" "time" - "github.com/kyverno/policy-reporter/pkg/report" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/metadata" + "k8s.io/client-go/metadata/metadatainformer" + "k8s.io/client-go/tools/cache" pr "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned" - "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions" - "github.com/kyverno/policy-reporter/pkg/crd/client/informers/externalversions/policyreport/v1alpha2" - "k8s.io/client-go/tools/cache" + "github.com/kyverno/policy-reporter/pkg/report" ) type k8sPolicyReportClient struct { - debouncer Debouncer - fatcory externalversions.SharedInformerFactory - v1alpha2 v1alpha2.Interface + queue *Queue + fatcory metadatainformer.SharedInformerFactory + polr informers.GenericInformer + cpolr informers.GenericInformer + metaClient metadata.Interface synced bool mx *sync.Mutex reportFilter *report.Filter @@ -27,13 +30,13 @@ func (k *k8sPolicyReportClient) HasSynced() bool { return k.synced } -func (k *k8sPolicyReportClient) Run(stopper chan struct{}) error { +func (k *k8sPolicyReportClient) Sync(stopper chan struct{}) error { var cpolrInformer cache.SharedIndexInformer - polrInformer := k.configurePolicyReport() + polrInformer := k.configureInformer(k.polr.Informer()) if !k.reportFilter.DisableClusterReports() { - cpolrInformer = k.configureClusterPolicyReport() + cpolrInformer = k.configureInformer(k.cpolr.Informer()) } k.fatcory.Start(stopper) @@ -51,86 +54,60 @@ func (k *k8sPolicyReportClient) Run(stopper chan struct{}) error { return nil } -func (k *k8sPolicyReportClient) configurePolicyReport() cache.SharedIndexInformer { - polrInformer := k.v1alpha2.PolicyReports().Informer() - polrInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - if item, ok := obj.(*pr.PolicyReport); ok { - if k.reportFilter.AllowReport(item) { - k.debouncer.Add(report.LifecycleEvent{NewPolicyReport: item, OldPolicyReport: nil, Type: report.Added}) - } - } - }, - DeleteFunc: func(obj interface{}) { - if item, ok := obj.(*pr.PolicyReport); ok { - if k.reportFilter.AllowReport(item) { - k.debouncer.Add(report.LifecycleEvent{NewPolicyReport: item, OldPolicyReport: nil, Type: report.Deleted}) - } - } - }, - UpdateFunc: func(oldObj, newObj interface{}) { - if item, ok := newObj.(*pr.PolicyReport); ok { - oldItem := oldObj.(*pr.PolicyReport) +func (k *k8sPolicyReportClient) Run(stopper chan struct{}) error { + if err := k.Sync(stopper); err != nil { + return err + } - if k.reportFilter.AllowReport(item) { - k.debouncer.Add(report.LifecycleEvent{NewPolicyReport: item, OldPolicyReport: oldItem, Type: report.Updated}) - } - } - }, - }) + k.queue.Run(5, stopper) - polrInformer.SetWatchErrorHandler(func(_ *cache.Reflector, _ error) { - k.synced = false - }) - - return polrInformer + return nil } -func (k *k8sPolicyReportClient) configureClusterPolicyReport() cache.SharedIndexInformer { - cpolrInformer := k.v1alpha2.ClusterPolicyReports().Informer() - cpolrInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ +func (k *k8sPolicyReportClient) configureInformer(informer cache.SharedIndexInformer) cache.SharedIndexInformer { + informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - if item, ok := obj.(*pr.ClusterPolicyReport); ok { + if item, ok := obj.(*v1.PartialObjectMetadata); ok { if k.reportFilter.AllowReport(item) { - k.debouncer.Add(report.LifecycleEvent{NewPolicyReport: item, OldPolicyReport: nil, Type: report.Added}) + k.queue.Add(item) } } }, DeleteFunc: func(obj interface{}) { - if item, ok := obj.(*pr.ClusterPolicyReport); ok { + if item, ok := obj.(*v1.PartialObjectMetadata); ok { if k.reportFilter.AllowReport(item) { - k.debouncer.Add(report.LifecycleEvent{NewPolicyReport: item, OldPolicyReport: nil, Type: report.Deleted}) + k.queue.Add(item) } } }, - UpdateFunc: func(oldObj, newObj interface{}) { - if item, ok := newObj.(*pr.ClusterPolicyReport); ok { - oldItem := oldObj.(*pr.ClusterPolicyReport) - + UpdateFunc: func(_, newObj interface{}) { + if item, ok := newObj.(*v1.PartialObjectMetadata); ok { if k.reportFilter.AllowReport(item) { - k.debouncer.Add(report.LifecycleEvent{NewPolicyReport: item, OldPolicyReport: oldItem, Type: report.Updated}) + k.queue.Add(item) } } }, }) - cpolrInformer.SetWatchErrorHandler(func(_ *cache.Reflector, _ error) { + informer.SetWatchErrorHandler(func(_ *cache.Reflector, _ error) { k.synced = false }) - return cpolrInformer + return informer } // NewPolicyReportClient new Client for Policy Report Kubernetes API -func NewPolicyReportClient(client versioned.Interface, reportFilter *report.Filter, publisher report.EventPublisher) report.PolicyReportClient { - fatcory := externalversions.NewSharedInformerFactory(client, time.Hour) - v1alpha2 := fatcory.Wgpolicyk8s().V1alpha2() +func NewPolicyReportClient(metaClient metadata.Interface, reportFilter *report.Filter, queue *Queue) report.PolicyReportClient { + fatcory := metadatainformer.NewSharedInformerFactory(metaClient, 15*time.Minute) + polr := fatcory.ForResource(pr.SchemeGroupVersion.WithResource("policyreports")) + cpolr := fatcory.ForResource(pr.SchemeGroupVersion.WithResource("clusterpolicyreports")) return &k8sPolicyReportClient{ fatcory: fatcory, - v1alpha2: v1alpha2, + polr: polr, + cpolr: cpolr, mx: &sync.Mutex{}, - debouncer: NewDebouncer(time.Minute, publisher), + queue: queue, reportFilter: reportFilter, } } diff --git a/pkg/kubernetes/policy_report_client_test.go b/pkg/kubernetes/policy_report_client_test.go index 82b5d451..bc34fcf8 100644 --- a/pkg/kubernetes/policy_report_client_test.go +++ b/pkg/kubernetes/policy_report_client_test.go @@ -6,12 +6,14 @@ import ( "testing" "time" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/workqueue" + + "github.com/kyverno/policy-reporter/pkg/cache" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/kubernetes" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/validate" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var filter = report.NewFilter(false, validate.RuleSets{}) @@ -31,19 +33,35 @@ func Test_PolicyReportWatcher(t *testing.T) { wg.Done() }) - kclient, rclient, _ := NewFakeCilent() - client := kubernetes.NewPolicyReportClient(kclient, filter, publisher) + restClient, polrClient, _ := NewFakeClient() - err := client.Run(stop) - if err != nil { - t.Fatal(err) - } + queue := kubernetes.NewQueue( + cache.NewInMermoryCache(), + kubernetes.NewDebouncer(0, publisher), + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test-queue"), + restClient.Wgpolicyk8sV1alpha2(), + ) - rclient.Create(ctx, fixtures.DefaultPolicyReport, metav1.CreateOptions{}) - time.Sleep(10 * time.Millisecond) - rclient.Update(ctx, fixtures.DefaultPolicyReport, metav1.UpdateOptions{}) - time.Sleep(10 * time.Millisecond) - rclient.Delete(ctx, fixtures.DefaultPolicyReport.Name, metav1.DeleteOptions{}) + kclient, rclient, _ := NewFakeMetaClient() + client := kubernetes.NewPolicyReportClient(kclient, filter, queue) + + go func() { + err := client.Run(stop) + if err != nil { + t.Error(err) + } + }() + + polrClient.Create(ctx, fixtures.DefaultPolicyReport, metav1.CreateOptions{}) + + rclient.CreateFake(fixtures.DefaultMeta, metav1.CreateOptions{}) + time.Sleep(1 * time.Second) + + rclient.UpdateFake(fixtures.DefaultMeta, metav1.UpdateOptions{}) + time.Sleep(1 * time.Second) + + polrClient.Delete(ctx, fixtures.DefaultPolicyReport.Name, metav1.DeleteOptions{}) + rclient.Delete(ctx, fixtures.DefaultMeta.Name, metav1.DeleteOptions{}) wg.Wait() @@ -51,6 +69,7 @@ func Test_PolicyReportWatcher(t *testing.T) { t.Error("Should receive the Added, Updated and Deleted Event") } } + func Test_ClusterPolicyReportWatcher(t *testing.T) { ctx := context.Background() stop := make(chan struct{}) @@ -65,18 +84,34 @@ func Test_ClusterPolicyReportWatcher(t *testing.T) { wg.Done() }) - kclient, _, rclient := NewFakeCilent() - client := kubernetes.NewPolicyReportClient(kclient, filter, publisher) + restClient, _, polrClient := NewFakeClient() - err := client.Run(stop) - if err != nil { - t.Fatal(err) - } + queue := kubernetes.NewQueue( + cache.NewInMermoryCache(), + kubernetes.NewDebouncer(0, publisher), + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test-queue"), + restClient.Wgpolicyk8sV1alpha2(), + ) - rclient.Create(ctx, fixtures.ClusterPolicyReport, metav1.CreateOptions{}) - time.Sleep(10 * time.Millisecond) - rclient.Update(ctx, fixtures.ClusterPolicyReport, metav1.UpdateOptions{}) - time.Sleep(10 * time.Millisecond) + kclient, _, rclient := NewFakeMetaClient() + client := kubernetes.NewPolicyReportClient(kclient, filter, queue) + + go func() { + err := client.Run(stop) + if err != nil { + t.Error(err) + } + }() + + polrClient.Create(ctx, fixtures.ClusterPolicyReport, metav1.CreateOptions{}) + + rclient.CreateFake(fixtures.DefaultClusterMeta, metav1.CreateOptions{}) + time.Sleep(1 * time.Second) + + rclient.UpdateFake(fixtures.DefaultClusterMeta, metav1.UpdateOptions{}) + time.Sleep(1 * time.Second) + + polrClient.Delete(ctx, fixtures.ClusterPolicyReport.Name, metav1.DeleteOptions{}) rclient.Delete(ctx, fixtures.ClusterPolicyReport.Name, metav1.DeleteOptions{}) wg.Wait() @@ -90,12 +125,21 @@ func Test_HasSynced(t *testing.T) { stop := make(chan struct{}) defer close(stop) - kclient, _, _ := NewFakeCilent() - client := kubernetes.NewPolicyReportClient(kclient, filter, report.NewEventPublisher()) + restClient, _, _ := NewFakeClient() - err := client.Run(stop) + queue := kubernetes.NewQueue( + cache.NewInMermoryCache(), + kubernetes.NewDebouncer(0, report.NewEventPublisher()), + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test-queue"), + restClient.Wgpolicyk8sV1alpha2(), + ) + + kclient, _, _ := NewFakeMetaClient() + client := kubernetes.NewPolicyReportClient(kclient, filter, queue) + + err := client.Sync(stop) if err != nil { - t.Fatal(err) + t.Error(err) } if client.HasSynced() != true { diff --git a/pkg/kubernetes/queue.go b/pkg/kubernetes/queue.go new file mode 100644 index 00000000..57af4125 --- /dev/null +++ b/pkg/kubernetes/queue.go @@ -0,0 +1,138 @@ +package kubernetes + +import ( + "context" + "log" + "time" + + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + + pr "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" +) + +type Queue struct { + queue workqueue.RateLimitingInterface + client v1alpha2.Wgpolicyk8sV1alpha2Interface + debouncer Debouncer + cache Cache +} + +func (q *Queue) Add(obj *v1.PartialObjectMetadata) error { + key, err := cache.MetaNamespaceKeyFunc(obj) + if err != nil { + return err + } + + q.queue.Add(key) + + return nil +} + +func (q *Queue) Run(workers int, stopCh chan struct{}) { + defer runtime.HandleCrash() + + defer q.queue.ShutDown() + + for i := 0; i < workers; i++ { + go wait.Until(q.runWorker, time.Second, stopCh) + } + + <-stopCh +} + +func (q *Queue) runWorker() { + for q.processNextItem() { + } +} + +func (q *Queue) processNextItem() bool { + key, quit := q.queue.Get() + if quit { + return false + } + + defer q.queue.Done(key) + + namespace, name, err := cache.SplitMetaNamespaceKey(key.(string)) + if err != nil { + q.queue.Forget(key) + return true + } + + var polr pr.ReportInterface + + if namespace == "" { + polr, err = q.client.ClusterPolicyReports().Get(context.Background(), name, v1.GetOptions{}) + } else { + polr, err = q.client.PolicyReports(namespace).Get(context.Background(), name, v1.GetOptions{}) + } + + if errors.IsNotFound(err) { + if namespace == "" { + polr = &pr.ClusterPolicyReport{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + }, + } + } else { + polr = &pr.PolicyReport{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + } + + q.debouncer.Add(report.LifecycleEvent{Type: report.Deleted, PolicyReport: polr}) + q.cache.RemoveItem(key.(string)) + + return true + } + + event := report.Added + if _, ok := q.cache.GetItem(key.(string)); ok { + event = report.Updated + } + + q.handleErr(err, key) + + q.debouncer.Add(report.LifecycleEvent{Type: event, PolicyReport: polr}) + q.cache.AddItem(key.(string), nil) + + return true +} + +func (q *Queue) handleErr(err error, key interface{}) { + if err == nil { + q.queue.Forget(key) + return + } + + if q.queue.NumRequeues(key) < 5 { + log.Printf("[ERROR] process report %v: %v", key, err) + + q.queue.AddRateLimited(key) + return + } + + q.queue.Forget(key) + + runtime.HandleError(err) + log.Printf("[WARNING] Dropping report %q out of the queue: %v", key, err) +} + +func NewQueue(cache Cache, debouncer Debouncer, queue workqueue.RateLimitingInterface, client v1alpha2.Wgpolicyk8sV1alpha2Interface) *Queue { + return &Queue{ + debouncer: debouncer, + queue: queue, + client: client, + cache: cache, + } +} diff --git a/pkg/kubernetes/secrets/client_test.go b/pkg/kubernetes/secrets/client_test.go index 6241db54..7a439c88 100644 --- a/pkg/kubernetes/secrets/client_test.go +++ b/pkg/kubernetes/secrets/client_test.go @@ -4,12 +4,13 @@ import ( "context" "testing" - "github.com/kyverno/policy-reporter/pkg/kubernetes/secrets" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" v1 "k8s.io/client-go/kubernetes/typed/core/v1" + + "github.com/kyverno/policy-reporter/pkg/kubernetes/secrets" ) const secretName = "secret-values" diff --git a/pkg/listener/fixture_test.go b/pkg/listener/fixture_test.go index 59034001..d0251346 100644 --- a/pkg/listener/fixture_test.go +++ b/pkg/listener/fixture_test.go @@ -1,9 +1,10 @@ package listener_test import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var preport1 = &v1alpha2.PolicyReport{ diff --git a/pkg/listener/metrics.go b/pkg/listener/metrics.go index 6b48e877..68f1949a 100644 --- a/pkg/listener/metrics.go +++ b/pkg/listener/metrics.go @@ -24,7 +24,7 @@ func NewMetricsListener( resultListeners := ResultListeners(filter, reportFilter, mode, fields) return func(event report.LifecycleEvent) { - if event.NewPolicyReport.GetNamespace() == "" { + if event.PolicyReport.GetNamespace() == "" { resultListeners[1](event) } else { resultListeners[0](event) diff --git a/pkg/listener/metrics/cache.go b/pkg/listener/metrics/cache.go new file mode 100644 index 00000000..2122b0b1 --- /dev/null +++ b/pkg/listener/metrics/cache.go @@ -0,0 +1,85 @@ +package metrics + +import ( + "strconv" + + gocache "github.com/patrickmn/go-cache" + "github.com/prometheus/client_golang/prometheus" + "github.com/segmentio/fasthash/fnv1a" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" +) + +type CacheItem struct { + Labels prometheus.Labels + Value float64 +} + +type Cache struct { + cache *gocache.Cache + filter *report.ResultFilter + labelGenerator LabelGenerator +} + +func (c *Cache) AddReport(polr v1alpha2.ReportInterface) { + labels := map[string]*CacheItem{} + for _, res := range polr.GetResults() { + if !c.filter.Validate(res) { + continue + } + + l := c.labelGenerator(polr, res) + + hash := labelHash(l) + + item, ok := labels[hash] + if !ok { + labels[hash] = &CacheItem{ + Labels: l, + Value: 1, + } + } else { + item.Value = item.Value + 1 + } + } + + list := make([]*CacheItem, 0, len(labels)) + for _, l := range labels { + list = append(list, l) + } + + c.cache.Set(polr.GetID(), list, gocache.NoExpiration) +} + +func (c *Cache) Remove(id string) { + c.cache.Delete(id) +} + +func (c *Cache) GetReportLabels(id string) []*CacheItem { + if item, ok := c.cache.Get(id); ok { + return item.([]*CacheItem) + } + + return []*CacheItem{{ + Labels: make(prometheus.Labels), + Value: 0, + }} +} + +func labelHash(labels prometheus.Labels) string { + h1 := fnv1a.Init64 + for i, v := range labels { + h1 = fnv1a.AddString64(h1, i+":"+v) + } + + return strconv.FormatUint(h1, 10) +} + +func NewCache(filter *report.ResultFilter, labelGenerator LabelGenerator) *Cache { + return &Cache{ + cache: gocache.New(gocache.NoExpiration, gocache.NoExpiration), + filter: filter, + labelGenerator: labelGenerator, + } +} diff --git a/pkg/listener/metrics/cluster_policy_report.go b/pkg/listener/metrics/cluster_policy_report.go index 8147c83c..e80daf9c 100644 --- a/pkg/listener/metrics/cluster_policy_report.go +++ b/pkg/listener/metrics/cluster_policy_report.go @@ -3,10 +3,11 @@ package metrics import ( "strings" - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/report" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) var clusterPolicyGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{ @@ -20,7 +21,7 @@ func CreateClusterPolicyReportMetricsListener(filter *report.ReportFilter) repor var newReport v1alpha2.ReportInterface return func(event report.LifecycleEvent) { - newReport = event.NewPolicyReport + newReport = event.PolicyReport if !filter.Validate(newReport) { return } diff --git a/pkg/listener/metrics/cluster_policy_report_test.go b/pkg/listener/metrics/cluster_policy_report_test.go index 94c3483b..c10e29e1 100644 --- a/pkg/listener/metrics/cluster_policy_report_test.go +++ b/pkg/listener/metrics/cluster_policy_report_test.go @@ -4,13 +4,14 @@ import ( "fmt" "testing" + "github.com/prometheus/client_golang/prometheus" + ioprometheusclient "github.com/prometheus/client_model/go" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/listener/metrics" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/validate" - "github.com/prometheus/client_golang/prometheus" - ioprometheusclient "github.com/prometheus/client_model/go" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_ClusterPolicyReportMetricGeneration(t *testing.T) { @@ -43,7 +44,7 @@ func Test_ClusterPolicyReportMetricGeneration(t *testing.T) { handler := metrics.CreateClusterPolicyReportMetricsListener(filter) t.Run("Added Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -75,8 +76,8 @@ func Test_ClusterPolicyReportMetricGeneration(t *testing.T) { }) t.Run("Modified Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -108,9 +109,9 @@ func Test_ClusterPolicyReportMetricGeneration(t *testing.T) { }) t.Run("Deleted Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) - handler(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: report2, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) + handler(report.LifecycleEvent{Type: report.Deleted, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -130,7 +131,7 @@ func Test_ClusterPolicyReportMetricGeneration(t *testing.T) { }) t.Run("Filtered Report", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report3, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report3}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { diff --git a/pkg/listener/metrics/cluster_result_detailed.go b/pkg/listener/metrics/cluster_result_detailed.go index 5d5f4587..44d2d27f 100644 --- a/pkg/listener/metrics/cluster_result_detailed.go +++ b/pkg/listener/metrics/cluster_result_detailed.go @@ -1,10 +1,11 @@ package metrics import ( - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/report" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) func RegisterDetailedClusterResultGauge(name string) *prometheus.GaugeVec { @@ -15,12 +16,10 @@ func RegisterDetailedClusterResultGauge(name string) *prometheus.GaugeVec { } func CreateDetailedClusterResultMetricListener(filter *report.ResultFilter, gauge *prometheus.GaugeVec) report.PolicyReportListener { - var newReport v1alpha2.ReportInterface - var oldReport v1alpha2.ReportInterface + cache := NewCache(filter, generateClusterResultLabels) return func(event report.LifecycleEvent) { - newReport = event.NewPolicyReport - oldReport = event.OldPolicyReport + newReport := event.PolicyReport switch event.Type { case report.Added: @@ -31,9 +30,12 @@ func CreateDetailedClusterResultMetricListener(filter *report.ResultFilter, gaug gauge.With(generateClusterResultLabels(newReport, result)).Set(1) } + + cache.AddReport(newReport) case report.Updated: - for _, result := range oldReport.GetResults() { - gauge.Delete(generateClusterResultLabels(oldReport, result)) + items := cache.GetReportLabels(newReport.GetID()) + for _, item := range items { + gauge.Delete(item.Labels) } for _, result := range newReport.GetResults() { @@ -43,19 +45,20 @@ func CreateDetailedClusterResultMetricListener(filter *report.ResultFilter, gaug gauge.With(generateClusterResultLabels(newReport, result)).Set(1) } - case report.Deleted: - for _, result := range newReport.GetResults() { - if !filter.Validate(result) { - continue - } - gauge.Delete(generateClusterResultLabels(newReport, result)) + cache.AddReport(newReport) + case report.Deleted: + items := cache.GetReportLabels(newReport.GetID()) + for _, item := range items { + gauge.Delete(item.Labels) } + + cache.Remove(newReport.GetID()) } } } -func generateClusterResultLabels(report v1alpha2.ReportInterface, result v1alpha2.PolicyReportResult) prometheus.Labels { +func generateClusterResultLabels(report v1alpha2.ReportInterface, result v1alpha2.PolicyReportResult) map[string]string { labels := prometheus.Labels{ "rule": result.Rule, "policy": result.Policy, diff --git a/pkg/listener/metrics/cluster_result_detailed_test.go b/pkg/listener/metrics/cluster_result_detailed_test.go index d9638258..f4b1a320 100644 --- a/pkg/listener/metrics/cluster_result_detailed_test.go +++ b/pkg/listener/metrics/cluster_result_detailed_test.go @@ -4,15 +4,16 @@ import ( "fmt" "testing" + "github.com/prometheus/client_golang/prometheus" + ioprometheusclient "github.com/prometheus/client_model/go" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/listener/metrics" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/validate" - "github.com/prometheus/client_golang/prometheus" - ioprometheusclient "github.com/prometheus/client_model/go" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_DetailedClusterResultMetricGeneration(t *testing.T) { @@ -40,7 +41,7 @@ func Test_DetailedClusterResultMetricGeneration(t *testing.T) { handler := metrics.CreateDetailedClusterResultMetricListener(filter, gauge) t.Run("Added Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -62,8 +63,8 @@ func Test_DetailedClusterResultMetricGeneration(t *testing.T) { }) t.Run("Modified Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -85,9 +86,9 @@ func Test_DetailedClusterResultMetricGeneration(t *testing.T) { }) t.Run("Deleted Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) - handler(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: report2, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) + handler(report.LifecycleEvent{Type: report.Deleted, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { diff --git a/pkg/listener/metrics/fixtures_test.go b/pkg/listener/metrics/fixtures_test.go index 6a07f276..d93e3b38 100644 --- a/pkg/listener/metrics/fixtures_test.go +++ b/pkg/listener/metrics/fixtures_test.go @@ -3,9 +3,10 @@ package metrics_test import ( "fmt" - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ioprometheusclient "github.com/prometheus/client_model/go" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" ) var preport = &v1alpha2.PolicyReport{ diff --git a/pkg/listener/metrics/model_test.go b/pkg/listener/metrics/model_test.go index 31484128..ac84a1c5 100644 --- a/pkg/listener/metrics/model_test.go +++ b/pkg/listener/metrics/model_test.go @@ -51,4 +51,13 @@ func Test_LabelMappings(t *testing.T) { if val, ok := results["status"]; !ok && val != string(fixtures.FailPodResult.Result) { t.Errorf("expected result for status label not found: %s", val) } + + metrics.LabelGeneratorMapping["name"](results, preport, fixtures.TrivyResult) + if val, ok := results["name"]; !ok && val != "" { + t.Errorf("expected empty name without resource, got: %s", val) + } + metrics.LabelGeneratorMapping["kind"](results, preport, fixtures.TrivyResult) + if val, ok := results["kind"]; !ok && val != "" { + t.Errorf("expected empty name without resource, got: %s", val) + } } diff --git a/pkg/listener/metrics/policy_report.go b/pkg/listener/metrics/policy_report.go index 3bf98f44..7960ab45 100644 --- a/pkg/listener/metrics/policy_report.go +++ b/pkg/listener/metrics/policy_report.go @@ -3,10 +3,11 @@ package metrics import ( "strings" - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/report" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) var policyGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{ @@ -20,7 +21,7 @@ func CreatePolicyReportMetricsListener(filter *report.ReportFilter) report.Polic var newReport v1alpha2.ReportInterface return func(event report.LifecycleEvent) { - newReport = event.NewPolicyReport + newReport = event.PolicyReport if !filter.Validate(newReport) { return } diff --git a/pkg/listener/metrics/policy_report_test.go b/pkg/listener/metrics/policy_report_test.go index fbeb0007..ccacfe11 100644 --- a/pkg/listener/metrics/policy_report_test.go +++ b/pkg/listener/metrics/policy_report_test.go @@ -3,12 +3,13 @@ package metrics_test import ( "testing" + "github.com/prometheus/client_golang/prometheus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/listener/metrics" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/validate" - "github.com/prometheus/client_golang/prometheus" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_PolicyReportMetricGeneration(t *testing.T) { @@ -43,7 +44,7 @@ func Test_PolicyReportMetricGeneration(t *testing.T) { t.Run("Added Metric", func(t *testing.T) { handler := metrics.CreatePolicyReportMetricsListener(filter) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -76,8 +77,8 @@ func Test_PolicyReportMetricGeneration(t *testing.T) { t.Run("Modified Metric", func(t *testing.T) { handler := metrics.CreatePolicyReportMetricsListener(filter) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -110,9 +111,9 @@ func Test_PolicyReportMetricGeneration(t *testing.T) { t.Run("Deleted Metric", func(t *testing.T) { handler := metrics.CreatePolicyReportMetricsListener(filter) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) - handler(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: report2, OldPolicyReport: report2}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) + handler(report.LifecycleEvent{Type: report.Deleted, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -127,7 +128,7 @@ func Test_PolicyReportMetricGeneration(t *testing.T) { t.Run("Validate Metric Filter", func(t *testing.T) { handler := metrics.CreatePolicyReportMetricsListener(filter) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report3, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report3}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { diff --git a/pkg/listener/metrics/result_custom.go b/pkg/listener/metrics/result_custom.go index 565562e8..c31658a0 100644 --- a/pkg/listener/metrics/result_custom.go +++ b/pkg/listener/metrics/result_custom.go @@ -1,12 +1,12 @@ package metrics import ( - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/report" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - dto "github.com/prometheus/client_model/go" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) func RegisterCustomResultGauge(name string, labelNames []string) *prometheus.GaugeVec { @@ -16,20 +16,20 @@ func RegisterCustomResultGauge(name string, labelNames []string) *prometheus.Gau }, labelNames) } -type LabelGenerator = func(v1alpha2.ReportInterface, v1alpha2.PolicyReportResult) map[string]string -type LabelCallback = func(map[string]string, v1alpha2.ReportInterface, v1alpha2.PolicyReportResult) +type ( + LabelGenerator = func(v1alpha2.ReportInterface, v1alpha2.PolicyReportResult) map[string]string + LabelCallback = func(map[string]string, v1alpha2.ReportInterface, v1alpha2.PolicyReportResult) +) func CreateCustomResultMetricsListener( filter *report.ResultFilter, gauge *prometheus.GaugeVec, labelGenerator LabelGenerator, ) report.PolicyReportListener { - var newReport v1alpha2.ReportInterface - var oldReport v1alpha2.ReportInterface + cache := NewCache(filter, labelGenerator) return func(event report.LifecycleEvent) { - newReport = event.NewPolicyReport - oldReport = event.OldPolicyReport + newReport := event.PolicyReport switch event.Type { case report.Added: @@ -40,13 +40,12 @@ func CreateCustomResultMetricsListener( gauge.With(labelGenerator(newReport, result)).Inc() } - case report.Updated: - for _, result := range oldReport.GetResults() { - if !filter.Validate(result) { - continue - } - decreaseOrDelete(gauge, labelGenerator(oldReport, result)) + cache.AddReport(newReport) + case report.Updated: + items := cache.GetReportLabels(newReport.GetID()) + for _, item := range items { + decreaseOrDelete(gauge, item.Labels, item.Value) } for _, result := range newReport.GetResults() { @@ -56,30 +55,31 @@ func CreateCustomResultMetricsListener( gauge.With(labelGenerator(newReport, result)).Inc() } - case report.Deleted: - for _, result := range newReport.GetResults() { - if !filter.Validate(result) { - continue - } - decreaseOrDelete(gauge, labelGenerator(newReport, result)) + cache.AddReport(newReport) + case report.Deleted: + items := cache.GetReportLabels(newReport.GetID()) + for _, item := range items { + decreaseOrDelete(gauge, item.Labels, item.Value) } + + cache.Remove(newReport.GetID()) } } } -func decreaseOrDelete(vec *prometheus.GaugeVec, labels map[string]string) { +func decreaseOrDelete(vec *prometheus.GaugeVec, labels map[string]string, gauge float64) { m := &dto.Metric{} err := vec.With(labels).Write(m) if err != nil { - vec.With(labels).Dec() + vec.With(labels).Sub(gauge) return } - if *m.Gauge.Value == 1 { + if *m.Gauge.Value-gauge == 0 { vec.Delete(labels) } else { - vec.With(labels).Dec() + vec.With(labels).Sub(gauge) } } diff --git a/pkg/listener/metrics/result_custom_test.go b/pkg/listener/metrics/result_custom_test.go index 7b877a98..59aab359 100644 --- a/pkg/listener/metrics/result_custom_test.go +++ b/pkg/listener/metrics/result_custom_test.go @@ -4,15 +4,16 @@ import ( "fmt" "testing" + "github.com/prometheus/client_golang/prometheus" + ioprometheusclient "github.com/prometheus/client_model/go" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/listener/metrics" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/validate" - "github.com/prometheus/client_golang/prometheus" - ioprometheusclient "github.com/prometheus/client_model/go" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_CustomResultMetricGeneration(t *testing.T) { @@ -26,7 +27,7 @@ func Test_CustomResultMetricGeneration(t *testing.T) { CreationTimestamp: v1.Now(), }, Summary: v1alpha2.PolicyReportSummary{Pass: 1, Fail: 1}, - Results: []v1alpha2.PolicyReportResult{fixtures.PassResult, fixtures.FailPodResult, fixtures.FailDisallowRuleResult}, + Results: []v1alpha2.PolicyReportResult{fixtures.PassResult, fixtures.PassResult, fixtures.FailPodResult, fixtures.FailDisallowRuleResult}, } report2 := &v1alpha2.PolicyReport{ @@ -44,7 +45,7 @@ func Test_CustomResultMetricGeneration(t *testing.T) { t.Run("Added Metric", func(t *testing.T) { handler := metrics.CreateCustomResultMetricsListener(filter, gauge, metrics.CreateLabelGenerator([]string{"namespace", "policy", "status", "source", "label:app"}, []string{"namespace", "policy", "status", "source", "app"})) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -60,7 +61,7 @@ func Test_CustomResultMetricGeneration(t *testing.T) { if err = testCustomResultMetricLabels(metrics[0], fixtures.FailPodResult, 1); err != nil { t.Error(err) } - if err = testCustomResultMetricLabels(metrics[1], fixtures.PassResult, 1); err != nil { + if err = testCustomResultMetricLabels(metrics[1], fixtures.PassResult, 2); err != nil { t.Error(err) } }) @@ -69,8 +70,8 @@ func Test_CustomResultMetricGeneration(t *testing.T) { gauge.Reset() handler := metrics.CreateCustomResultMetricsListener(filter, gauge, metrics.CreateLabelGenerator([]string{"namespace", "policy", "status", "source", "label:app"}, []string{"namespace", "policy", "status", "source", "app"})) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -95,9 +96,9 @@ func Test_CustomResultMetricGeneration(t *testing.T) { gauge.Reset() handler := metrics.CreateCustomResultMetricsListener(filter, gauge, metrics.CreateLabelGenerator([]string{"namespace", "policy", "status", "source", "label:app"}, []string{"namespace", "policy", "status", "source", "app"})) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) - handler(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: report2, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) + handler(report.LifecycleEvent{Type: report.Deleted, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -114,9 +115,9 @@ func Test_CustomResultMetricGeneration(t *testing.T) { gauge.Reset() handler := metrics.CreateCustomResultMetricsListener(filter, gauge, metrics.CreateLabelGenerator([]string{"namespace", "policy", "status", "source", "label:app"}, []string{"namespace", "policy", "status", "source", "app"})) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: report1, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Deleted, PolicyReport: report1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -135,7 +136,7 @@ func Test_CustomResultMetricGeneration(t *testing.T) { if err = testCustomResultMetricLabels(metrics[0], fixtures.FailPodResult, 1); err != nil { t.Error(err) } - if err = testCustomResultMetricLabels(metrics[1], fixtures.PassResult, 1); err != nil { + if err = testCustomResultMetricLabels(metrics[1], fixtures.PassResult, 2); err != nil { t.Error(err) } }) diff --git a/pkg/listener/metrics/result_detailed.go b/pkg/listener/metrics/result_detailed.go index 6a7777e7..9f19ae18 100644 --- a/pkg/listener/metrics/result_detailed.go +++ b/pkg/listener/metrics/result_detailed.go @@ -1,10 +1,11 @@ package metrics import ( - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/report" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) func RegisterDetailedResultGauge(name string) *prometheus.GaugeVec { @@ -15,12 +16,10 @@ func RegisterDetailedResultGauge(name string) *prometheus.GaugeVec { } func CreateDetailedResultMetricListener(filter *report.ResultFilter, gauge *prometheus.GaugeVec) report.PolicyReportListener { - var newReport v1alpha2.ReportInterface - var oldReport v1alpha2.ReportInterface + cache := NewCache(filter, generateResultLabels) return func(event report.LifecycleEvent) { - newReport = event.NewPolicyReport - oldReport = event.OldPolicyReport + newReport := event.PolicyReport switch event.Type { case report.Added: @@ -31,9 +30,12 @@ func CreateDetailedResultMetricListener(filter *report.ResultFilter, gauge *prom gauge.With(generateResultLabels(newReport, result)).Set(1) } + + cache.AddReport(newReport) case report.Updated: - for _, result := range oldReport.GetResults() { - gauge.Delete(generateResultLabels(oldReport, result)) + items := cache.GetReportLabels(newReport.GetID()) + for _, item := range items { + gauge.Delete(item.Labels) } for _, result := range newReport.GetResults() { @@ -43,19 +45,20 @@ func CreateDetailedResultMetricListener(filter *report.ResultFilter, gauge *prom gauge.With(generateResultLabels(newReport, result)).Set(1) } - case report.Deleted: - for _, result := range newReport.GetResults() { - if !filter.Validate(result) { - continue - } - gauge.Delete(generateResultLabels(newReport, result)) + cache.AddReport(newReport) + case report.Deleted: + items := cache.GetReportLabels(newReport.GetID()) + for _, item := range items { + gauge.Delete(item.Labels) } + + cache.Remove(newReport.GetID()) } } } -func generateResultLabels(report v1alpha2.ReportInterface, result v1alpha2.PolicyReportResult) prometheus.Labels { +func generateResultLabels(report v1alpha2.ReportInterface, result v1alpha2.PolicyReportResult) map[string]string { labels := prometheus.Labels{ "namespace": report.GetNamespace(), "rule": result.Rule, diff --git a/pkg/listener/metrics/result_detailed_test.go b/pkg/listener/metrics/result_detailed_test.go index 1ae9a243..12fe3705 100644 --- a/pkg/listener/metrics/result_detailed_test.go +++ b/pkg/listener/metrics/result_detailed_test.go @@ -4,15 +4,16 @@ import ( "fmt" "testing" + "github.com/prometheus/client_golang/prometheus" + ioprometheusclient "github.com/prometheus/client_model/go" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/listener/metrics" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/validate" - "github.com/prometheus/client_golang/prometheus" - ioprometheusclient "github.com/prometheus/client_model/go" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_DetailedResultMetricGeneration(t *testing.T) { @@ -42,7 +43,7 @@ func Test_DetailedResultMetricGeneration(t *testing.T) { handler := metrics.CreateDetailedResultMetricListener(filter, gauge) t.Run("Added Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -64,8 +65,8 @@ func Test_DetailedResultMetricGeneration(t *testing.T) { }) t.Run("Modified Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -87,9 +88,9 @@ func Test_DetailedResultMetricGeneration(t *testing.T) { }) t.Run("Deleted Metric", func(t *testing.T) { - handler(report.LifecycleEvent{Type: report.Added, NewPolicyReport: report1, OldPolicyReport: nil}) - handler(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: report2, OldPolicyReport: report1}) - handler(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: report2, OldPolicyReport: nil}) + handler(report.LifecycleEvent{Type: report.Added, PolicyReport: report1}) + handler(report.LifecycleEvent{Type: report.Updated, PolicyReport: report2}) + handler(report.LifecycleEvent{Type: report.Deleted, PolicyReport: report2}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { diff --git a/pkg/listener/metrics_test.go b/pkg/listener/metrics_test.go index 9fc3db11..61b156ed 100644 --- a/pkg/listener/metrics_test.go +++ b/pkg/listener/metrics_test.go @@ -3,12 +3,12 @@ package listener_test import ( "testing" + "github.com/prometheus/client_golang/prometheus" + ioprometheusclient "github.com/prometheus/client_model/go" + "github.com/kyverno/policy-reporter/pkg/listener" "github.com/kyverno/policy-reporter/pkg/listener/metrics" "github.com/kyverno/policy-reporter/pkg/report" - - "github.com/prometheus/client_golang/prometheus" - ioprometheusclient "github.com/prometheus/client_model/go" ) func Test_SimpleMetricsListener(t *testing.T) { @@ -18,7 +18,7 @@ func Test_SimpleMetricsListener(t *testing.T) { slistener := listener.NewMetricsListener(&report.ResultFilter{}, &report.ReportFilter{}, metrics.Simple, make([]string, 0)) t.Run("Add ClusterPolicyReport Metric", func(t *testing.T) { - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: creport, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: creport}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -35,7 +35,7 @@ func Test_SimpleMetricsListener(t *testing.T) { } }) t.Run("Add PolicyReport Metric", func(t *testing.T) { - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: preport1, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: preport1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -61,7 +61,7 @@ func Test_CustomMetricsListener(t *testing.T) { slistener := listener.NewMetricsListener(&report.ResultFilter{}, &report.ReportFilter{}, metrics.Custom, customFields) t.Run("Add ClusterPolicyReport Metric", func(t *testing.T) { - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: creport, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: creport}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -78,7 +78,7 @@ func Test_CustomMetricsListener(t *testing.T) { } }) t.Run("Add PolicyReport Metric", func(t *testing.T) { - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: preport1, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: preport1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -103,7 +103,7 @@ func Test_MetricsListener(t *testing.T) { slistener := listener.NewMetricsListener(&report.ResultFilter{}, &report.ReportFilter{}, metrics.Detailed, make([]string, 0)) t.Run("Add ClusterPolicyReport Metric", func(t *testing.T) { - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: creport, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: creport}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { @@ -120,7 +120,7 @@ func Test_MetricsListener(t *testing.T) { } }) t.Run("Add PolicyReport Metric", func(t *testing.T) { - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: preport1, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: preport1}) metricFam, err := prometheus.DefaultGatherer.Gather() if err != nil { diff --git a/pkg/listener/new_result.go b/pkg/listener/new_result.go index 7bcdb264..db08dfca 100644 --- a/pkg/listener/new_result.go +++ b/pkg/listener/new_result.go @@ -6,6 +6,7 @@ import ( "github.com/kyverno/policy-reporter/pkg/cache" "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/helper" "github.com/kyverno/policy-reporter/pkg/report" ) @@ -23,36 +24,32 @@ func (l *ResultListener) RegisterListener(listener report.PolicyReportResultList } func (l *ResultListener) Listen(event report.LifecycleEvent) { - if event.OldPolicyReport != nil && len(event.OldPolicyReport.GetResults()) > 0 { - for _, result := range event.OldPolicyReport.GetResults() { - l.cache.Add(result.ID) - } + if event.Type != report.Added && event.Type != report.Updated { + l.cache.RemoveReport(event.PolicyReport.GetID()) + return } - if event.Type != report.Added && event.Type != report.Updated { + if len(event.PolicyReport.GetResults()) == 0 { return } var preExisted bool if event.Type == report.Added { - preExisted = event.NewPolicyReport.GetCreationTimestamp().Local().Before(l.startUp) + preExisted = event.PolicyReport.GetCreationTimestamp().Local().Before(l.startUp) if l.skipExisting && preExisted { + l.cache.AddReport(event.PolicyReport) return } } - if len(event.NewPolicyReport.GetResults()) == 0 { - return - } - - diff := report.FindNewResults(event.NewPolicyReport, event.OldPolicyReport) - wg := sync.WaitGroup{} - for _, r := range diff { - if found := l.cache.Has(r.GetID()); found { + existing := l.cache.GetResults(event.PolicyReport.GetID()) + + for _, r := range event.PolicyReport.GetResults() { + if helper.Contains(r.GetID(), existing) { continue } @@ -60,12 +57,14 @@ func (l *ResultListener) Listen(event report.LifecycleEvent) { for _, cb := range l.listener { go func(callback report.PolicyReportResultListener, result v1alpha2.PolicyReportResult) { - callback(event.NewPolicyReport, result, preExisted) + callback(event.PolicyReport, result, preExisted) wg.Done() }(cb, r) } } + l.cache.AddReport(event.PolicyReport) + wg.Wait() } diff --git a/pkg/listener/new_result_test.go b/pkg/listener/new_result_test.go index c4bb774f..3147e2f0 100644 --- a/pkg/listener/new_result_test.go +++ b/pkg/listener/new_result_test.go @@ -15,27 +15,28 @@ func Test_ResultListener(t *testing.T) { t.Run("Publish Result", func(t *testing.T) { var called v1alpha2.PolicyReportResult - slistener := listener.NewResultListener(true, cache.NewInMermoryCache(0, 5*time.Minute), time.Now()) + slistener := listener.NewResultListener(true, cache.NewInMermoryCache(), time.Now()) slistener.RegisterListener(func(_ v1alpha2.ReportInterface, r v1alpha2.PolicyReportResult, b bool) { called = r }) - slistener.Listen(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: preport2, OldPolicyReport: preport1}) + slistener.Listen(report.LifecycleEvent{Type: report.Added, PolicyReport: preport1}) + slistener.Listen(report.LifecycleEvent{Type: report.Updated, PolicyReport: preport2}) if called.GetID() != fixtures.FailPodResult.GetID() { - t.Error("Expected Listener to be called with Result2") + t.Error("Expected Listener to be called with FailPodResult") } }) t.Run("Ignore Delete Event", func(t *testing.T) { var called bool - slistener := listener.NewResultListener(true, cache.NewInMermoryCache(0, 5*time.Minute), time.Now()) + slistener := listener.NewResultListener(true, cache.NewInMermoryCache(), time.Now()) slistener.RegisterListener(func(_ v1alpha2.ReportInterface, r v1alpha2.PolicyReportResult, b bool) { called = true }) - slistener.Listen(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: preport2, OldPolicyReport: preport1}) + slistener.Listen(report.LifecycleEvent{Type: report.Deleted, PolicyReport: preport2}) if called { t.Error("Expected Listener not be called on Deleted event") @@ -45,12 +46,12 @@ func Test_ResultListener(t *testing.T) { t.Run("Ignore Added Results created before startup", func(t *testing.T) { var called bool - slistener := listener.NewResultListener(true, cache.NewInMermoryCache(0, 5*time.Minute), time.Now()) + slistener := listener.NewResultListener(true, cache.NewInMermoryCache(), time.Now()) slistener.RegisterListener(func(_ v1alpha2.ReportInterface, r v1alpha2.PolicyReportResult, b bool) { called = true }) - slistener.Listen(report.LifecycleEvent{Type: report.Added, NewPolicyReport: preport2, OldPolicyReport: preport1}) + slistener.Listen(report.LifecycleEvent{Type: report.Added, PolicyReport: preport2}) if called { t.Error("Expected Listener not be called on Deleted event") @@ -60,15 +61,15 @@ func Test_ResultListener(t *testing.T) { t.Run("Ignore CacheResults", func(t *testing.T) { var called bool - rcache := cache.NewInMermoryCache(0, 5*time.Minute) - rcache.Add(fixtures.FailPodResult.ID) + rcache := cache.NewInMermoryCache() slistener := listener.NewResultListener(true, rcache, time.Now()) slistener.RegisterListener(func(_ v1alpha2.ReportInterface, r v1alpha2.PolicyReportResult, b bool) { called = true }) - slistener.Listen(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: preport2, OldPolicyReport: preport1}) + slistener.Listen(report.LifecycleEvent{Type: report.Added, PolicyReport: preport2}) + slistener.Listen(report.LifecycleEvent{Type: report.Updated, PolicyReport: preport2}) if called { t.Error("Expected Listener not be called on cached results") @@ -78,15 +79,14 @@ func Test_ResultListener(t *testing.T) { t.Run("Early Return if Results are empty", func(t *testing.T) { var called bool - rcache := cache.NewInMermoryCache(0, 5*time.Minute) - rcache.Add(fixtures.FailPodResult.ID) + rcache := cache.NewInMermoryCache() slistener := listener.NewResultListener(true, rcache, time.Now()) slistener.RegisterListener(func(_ v1alpha2.ReportInterface, r v1alpha2.PolicyReportResult, b bool) { called = true }) - slistener.Listen(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: preport3, OldPolicyReport: preport1}) + slistener.Listen(report.LifecycleEvent{Type: report.Updated, PolicyReport: preport3}) if called { t.Error("Expected Listener not be called with empty results") diff --git a/pkg/listener/send_result.go b/pkg/listener/send_result.go index 8bc75800..d0ff12e8 100644 --- a/pkg/listener/send_result.go +++ b/pkg/listener/send_result.go @@ -19,7 +19,9 @@ func NewSendResultListener(clients []target.Client, mapper report.Mapper) report go func(target target.Client, re v1alpha2.ReportInterface, result v1alpha2.PolicyReportResult, preExisted bool) { defer wg.Done() - result.Priority = mapper.ResolvePriority(result.Policy, result.Severity) + if result.Result == v1alpha2.StatusFail { + result.Priority = mapper.ResolvePriority(result.Policy, result.Severity) + } if (preExisted && target.SkipExistingOnStartup()) || !target.Validate(re, result) { return diff --git a/pkg/listener/store.go b/pkg/listener/store.go index 93ac3b24..e5f89b87 100644 --- a/pkg/listener/store.go +++ b/pkg/listener/store.go @@ -11,16 +11,16 @@ const Store = "store_listener" func NewStoreListener(store report.PolicyReportStore) report.PolicyReportListener { return func(event report.LifecycleEvent) { if event.Type == report.Deleted { - logOnError("remove", event.NewPolicyReport.GetName(), store.Remove(event.NewPolicyReport.GetID())) + logOnError("remove", event.PolicyReport.GetName(), store.Remove(event.PolicyReport.GetID())) return } if event.Type == report.Updated { - logOnError("update", event.NewPolicyReport.GetName(), store.Update(event.NewPolicyReport)) + logOnError("update", event.PolicyReport.GetName(), store.Update(event.PolicyReport)) return } - logOnError("add", event.NewPolicyReport.GetName(), store.Add(event.NewPolicyReport)) + logOnError("add", event.PolicyReport.GetName(), store.Add(event.PolicyReport)) } } diff --git a/pkg/listener/store_test.go b/pkg/listener/store_test.go index 146934eb..12130e4d 100644 --- a/pkg/listener/store_test.go +++ b/pkg/listener/store_test.go @@ -12,7 +12,7 @@ func Test_StoreListener(t *testing.T) { t.Run("Save New Report", func(t *testing.T) { slistener := listener.NewStoreListener(store) - slistener(report.LifecycleEvent{Type: report.Added, NewPolicyReport: preport1, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Added, PolicyReport: preport1}) if _, ok := store.Get(preport1.GetID()); !ok { t.Error("Expected Report to be stored") @@ -20,7 +20,7 @@ func Test_StoreListener(t *testing.T) { }) t.Run("Update Modified Report", func(t *testing.T) { slistener := listener.NewStoreListener(store) - slistener(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: preport2, OldPolicyReport: preport1}) + slistener(report.LifecycleEvent{Type: report.Updated, PolicyReport: preport2}) if preport, ok := store.Get(preport2.GetID()); !ok && len(preport.GetResults()) == 2 { t.Error("Expected Report to be updated") @@ -28,7 +28,7 @@ func Test_StoreListener(t *testing.T) { }) t.Run("Remove Deleted Report", func(t *testing.T) { slistener := listener.NewStoreListener(store) - slistener(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: preport2, OldPolicyReport: nil}) + slistener(report.LifecycleEvent{Type: report.Deleted, PolicyReport: preport2}) if _, ok := store.Get(preport2.GetID()); ok { t.Error("Expected Report to be removed") diff --git a/pkg/report/client.go b/pkg/report/client.go index 9ef6979b..3f81714a 100644 --- a/pkg/report/client.go +++ b/pkg/report/client.go @@ -10,8 +10,10 @@ type PolicyReportResultListener = func(v1alpha2.ReportInterface, v1alpha2.Policy // PolicyReportClient watches for PolicyReport Events and executes registered callback type PolicyReportClient interface { - // Run WatchPolicyReports starts to watch for PolicyReport LifecycleEvent events + // Run starts the informer and workerqueue Run(stopper chan struct{}) error + // Sync Report Informer and start watching for events + Sync(stopper chan struct{}) error // HasSynced the configured PolicyReport HasSynced() bool } diff --git a/pkg/report/filter.go b/pkg/report/filter.go index fe09c6a4..56c3c3de 100644 --- a/pkg/report/filter.go +++ b/pkg/report/filter.go @@ -5,6 +5,10 @@ import ( "github.com/kyverno/policy-reporter/pkg/validate" ) +type Namespaced interface { + GetNamespace() string +} + type Filter struct { disbaleClusterReports bool namespace validate.RuleSets @@ -14,7 +18,7 @@ func (f *Filter) DisableClusterReports() bool { return f.disbaleClusterReports } -func (f *Filter) AllowReport(report v1alpha2.ReportInterface) bool { +func (f *Filter) AllowReport(report Namespaced) bool { return validate.Namespace(report.GetNamespace(), f.namespace) } diff --git a/pkg/report/filter_test.go b/pkg/report/filter_test.go index aaede479..dbdfb250 100644 --- a/pkg/report/filter_test.go +++ b/pkg/report/filter_test.go @@ -16,6 +16,7 @@ func Test_DisableClusterReports(t *testing.T) { t.Error("Expected EnableClusterReports to return true as configured") } } + func Test_AllowReport(t *testing.T) { t.Run("Allow ClusterReport", func(t *testing.T) { filter := report.NewFilter(true, validate.RuleSets{Exclude: []string{"*"}}) diff --git a/pkg/report/model.go b/pkg/report/model.go index 4277a2eb..6359b81f 100644 --- a/pkg/report/model.go +++ b/pkg/report/model.go @@ -29,9 +29,8 @@ const ( // LifecycleEvent of PolicyReports type LifecycleEvent struct { - Type Event - NewPolicyReport v1alpha2.ReportInterface - OldPolicyReport v1alpha2.ReportInterface + Type Event + PolicyReport v1alpha2.ReportInterface } // ResourceType Enum defined for PolicyReport diff --git a/pkg/report/model_test.go b/pkg/report/model_test.go index 31f2aa26..92a778c1 100644 --- a/pkg/report/model_test.go +++ b/pkg/report/model_test.go @@ -3,10 +3,11 @@ package report_test import ( "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/report" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var preport = &v1alpha2.PolicyReport{ diff --git a/pkg/report/publisher_test.go b/pkg/report/publisher_test.go index 0a034bbf..022e03c4 100644 --- a/pkg/report/publisher_test.go +++ b/pkg/report/publisher_test.go @@ -4,16 +4,17 @@ import ( "sync" "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/report" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_PublishLifecycleEvents(t *testing.T) { var event report.LifecycleEvent wg := sync.WaitGroup{} - wg.Add(1) + wg.Add(2) publisher := report.NewEventPublisher() publisher.RegisterListener("test", func(le report.LifecycleEvent) { @@ -21,12 +22,14 @@ func Test_PublishLifecycleEvents(t *testing.T) { wg.Done() }) - publisher.Publish(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: &v1alpha2.PolicyReport{ + publisher.Publish(report.LifecycleEvent{Type: report.Added, PolicyReport: &v1alpha2.PolicyReport{ ObjectMeta: v1.ObjectMeta{ Name: "polr-test", Namespace: "test", }, - }, OldPolicyReport: &v1alpha2.PolicyReport{ + }}) + + publisher.Publish(report.LifecycleEvent{Type: report.Updated, PolicyReport: &v1alpha2.PolicyReport{ ObjectMeta: v1.ObjectMeta{ Name: "polr-test", Namespace: "test", @@ -52,18 +55,13 @@ func Test_PublishDeleteLifecycleEvents(t *testing.T) { wg.Done() }) - publisher.Publish(report.LifecycleEvent{Type: report.Updated, NewPolicyReport: &v1alpha2.PolicyReport{ - ObjectMeta: v1.ObjectMeta{ - Name: "polr-test", - Namespace: "test", - }, - }, OldPolicyReport: &v1alpha2.PolicyReport{ + publisher.Publish(report.LifecycleEvent{Type: report.Added, PolicyReport: &v1alpha2.PolicyReport{ ObjectMeta: v1.ObjectMeta{ Name: "polr-test", Namespace: "test", }, }}) - publisher.Publish(report.LifecycleEvent{Type: report.Deleted, NewPolicyReport: &v1alpha2.PolicyReport{ + publisher.Publish(report.LifecycleEvent{Type: report.Deleted, PolicyReport: &v1alpha2.PolicyReport{ ObjectMeta: v1.ObjectMeta{ Name: "polr-test", Namespace: "test", diff --git a/pkg/report/store_test.go b/pkg/report/store_test.go index 13db1419..17f5264d 100644 --- a/pkg/report/store_test.go +++ b/pkg/report/store_test.go @@ -3,9 +3,10 @@ package report_test import ( "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/report" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_PolicyReportStore(t *testing.T) { diff --git a/pkg/sqlite3/store.go b/pkg/sqlite3/store.go index e0b08387..03b8b1b9 100644 --- a/pkg/sqlite3/store.go +++ b/pkg/sqlite3/store.go @@ -9,13 +9,13 @@ import ( "strings" "time" - api "github.com/kyverno/policy-reporter/pkg/api/v1" - "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" - "github.com/kyverno/policy-reporter/pkg/report" + _ "github.com/mattn/go-sqlite3" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - _ "github.com/mattn/go-sqlite3" + api "github.com/kyverno/policy-reporter/pkg/api/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" + "github.com/kyverno/policy-reporter/pkg/report" ) const ( @@ -261,7 +261,7 @@ func (s *policyReportStore) FetchPolicyReports(filter api.Filter, pagination api paginationString := generatePagination(pagination) where = strings.Join(whereParts, " AND ") - var list = make([]*api.PolicyReport, 0) + list := make([]*api.PolicyReport, 0) rows, err := s.db.Query(`SELECT id, namespace, source, name, labels, pass, skip, warn, fail, error FROM policy_report as report WHERE `+where+" "+paginationString, args...) if err != nil { @@ -343,7 +343,7 @@ func (s *policyReportStore) FetchClusterPolicyReports(filter api.Filter, paginat paginationString := generatePagination(pagination) where = strings.Join(whereParts, " AND ") - var list = make([]*api.PolicyReport, 0) + list := make([]*api.PolicyReport, 0) rows, err := s.db.Query(`SELECT id, source, name, labels, pass, skip, warn, fail, error FROM policy_report as report WHERE `+where+" "+paginationString, args...) if err != nil { @@ -776,7 +776,6 @@ func (s *policyReportStore) FetchNamespacedStatusCounts(filter api.Filter) ([]ap FROM policy_report_result as result`+join+` WHERE resource_namespace != ""`+where+` GROUP BY resource_namespace, status ORDER BY resource_namespace ASC`, args...) - if err != nil { return statusCounts, err } @@ -830,7 +829,6 @@ func (s *policyReportStore) FetchRuleStatusCounts(policy, rule string) ([]api.St SELECT COUNT(id) as counter, status FROM policy_report_result as result`+whereClause+` GROUP BY status`, args...) - if err != nil { return statusCounts, err } @@ -887,7 +885,6 @@ func (s *policyReportStore) FetchStatusCounts(filter api.Filter) ([]api.StatusCo SELECT COUNT(result.id) as counter, status FROM policy_report_result as result`+join+` WHERE resource_namespace = ""`+where+` GROUP BY status`, args...) - if err != nil { return statusCounts, err } @@ -926,7 +923,6 @@ func (s *policyReportStore) FetchNamespacedResults(filter api.Filter, pagination rows, err := s.db.Query(` SELECT result.id, resource_namespace, resource_kind, resource_api_version, resource_name, message, policy, rule, severity, properties, status, category, timestamp FROM policy_report_result as result`+join+` WHERE resource_namespace != ""`+where+` `+paginationString, args...) - if err != nil { return list, err } @@ -987,7 +983,6 @@ func (s *policyReportStore) FetchClusterResults(filter api.Filter, pagination ap rows, err := s.db.Query(` SELECT result.id, resource_namespace, resource_kind, resource_api_version, resource_name, message, policy, rule, severity, properties, status, category, timestamp FROM policy_report_result as result`+join+` WHERE resource_namespace =""`+where+` `+paginationString, args...) - if err != nil { return list, err } diff --git a/pkg/sqlite3/store_test.go b/pkg/sqlite3/store_test.go index 863b8814..599d9e35 100644 --- a/pkg/sqlite3/store_test.go +++ b/pkg/sqlite3/store_test.go @@ -3,11 +3,12 @@ package sqlite3_test import ( "testing" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "github.com/kyverno/policy-reporter/pkg/api/v1" "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/sqlite3" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var pagination = v1.Pagination{Page: 1, Offset: 20, Direction: "ASC", SortBy: []string{"resource_name"}} diff --git a/pkg/target/client.go b/pkg/target/client.go index cbeba3e3..11234bb9 100644 --- a/pkg/target/client.go +++ b/pkg/target/client.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/kyverno/go-wildcard" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/helper" "github.com/kyverno/policy-reporter/pkg/report" diff --git a/pkg/target/client_test.go b/pkg/target/client_test.go index 040b8909..90f64be7 100644 --- a/pkg/target/client_test.go +++ b/pkg/target/client_test.go @@ -3,12 +3,13 @@ package target_test import ( "testing" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2" "github.com/kyverno/policy-reporter/pkg/fixtures" "github.com/kyverno/policy-reporter/pkg/report" "github.com/kyverno/policy-reporter/pkg/target" "github.com/kyverno/policy-reporter/pkg/validate" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var preport = &v1alpha2.PolicyReport{ diff --git a/pkg/target/loki/loki.go b/pkg/target/loki/loki.go index abe617ae..9513ea12 100644 --- a/pkg/target/loki/loki.go +++ b/pkg/target/loki/loki.go @@ -40,7 +40,7 @@ func newLokiPayload(result v1alpha2.PolicyReportResult, customLabels map[string] le := entry{Ts: timestamp.Format(time.RFC3339), Line: "[" + strings.ToUpper(result.Priority.String()) + "] " + result.Message} ls := stream{Entries: []entry{le}} - var labels = []string{ + labels := []string{ "status=\"" + string(result.Result) + "\"", "policy=\"" + result.Policy + "\"", "priority=\"" + result.Priority.String() + "\"", diff --git a/pkg/validate/validate.go b/pkg/validate/validate.go index 8710383c..538f50b1 100644 --- a/pkg/validate/validate.go +++ b/pkg/validate/validate.go @@ -2,6 +2,7 @@ package validate import ( "github.com/kyverno/go-wildcard" + "github.com/kyverno/policy-reporter/pkg/helper" ) diff --git a/pkg/validate/validate_test.go b/pkg/validate/validate_test.go index 1779aadd..399ced9d 100644 --- a/pkg/validate/validate_test.go +++ b/pkg/validate/validate_test.go @@ -8,7 +8,6 @@ import ( func Test_Validations(t *testing.T) { t.Run("Validate Source", func(t *testing.T) { - if validate.ContainsRuleSet("test", validate.RuleSets{Include: []string{"jsPolicy"}}) { t.Errorf("Unexpected Validation Result") }