1
0
Fork 0
mirror of https://github.com/kyverno/policy-reporter.git synced 2024-12-14 11:57:32 +00:00

Implement MetadataClient (#257)

* Implement MetadataClient

Signed-off-by: Frank Jogeleit <frank.jogeleit@web.de>
This commit is contained in:
Frank Jogeleit 2023-02-08 15:53:59 +01:00 committed by GitHub
parent b96b1b2995
commit f3b980bfd3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
92 changed files with 1031 additions and 578 deletions

View file

@ -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 .

View file

@ -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()
},

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

39
go.mod
View file

@ -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
)

167
go.sum
View file

@ -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=

View file

@ -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

View file

@ -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()

14
pkg/cache/cache.go vendored
View file

@ -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)
}

50
pkg/cache/memory.go vendored
View file

@ -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),
}
}

35
pkg/cache/redis.go vendored
View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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{})

View file

@ -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

View file

@ -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)

View file

@ -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) {

View file

@ -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) {

View file

@ -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

View file

@ -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 {

View file

@ -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.

View file

@ -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()

View file

@ -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()

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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.

View file

@ -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 {

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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) {

View file

@ -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()

View file

@ -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 {

View file

@ -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{})

View file

@ -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{})

View file

@ -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()

View file

@ -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 {

View file

@ -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{})

View file

@ -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{})

View file

@ -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",

View file

@ -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/",

View file

@ -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()

7
pkg/kubernetes/cache.go Normal file
View file

@ -0,0 +1,7 @@
package kubernetes
type Cache interface {
AddItem(string, interface{})
GetItem(string) (interface{}, bool)
RemoveItem(string)
}

View file

@ -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)

View file

@ -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()

View file

@ -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()

View file

@ -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,
}
}

View file

@ -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 {

138
pkg/kubernetes/queue.go Normal file
View file

@ -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,
}
}

View file

@ -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"

View file

@ -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{

View file

@ -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)

View file

@ -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,
}
}

View file

@ -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
}

View file

@ -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 {

View file

@ -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,

View file

@ -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 {

View file

@ -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{

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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 {

View file

@ -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)
}
}

View file

@ -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)
}
})

View file

@ -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,

View file

@ -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 {

View file

@ -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 {

View file

@ -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()
}

View file

@ -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")

View file

@ -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

View file

@ -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))
}
}

View file

@ -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")

View file

@ -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
}

View file

@ -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)
}

View file

@ -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{"*"}})

View file

@ -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

View file

@ -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{

View file

@ -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",

View file

@ -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) {

View file

@ -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
}

View file

@ -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"}}

View file

@ -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"

View file

@ -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{

View file

@ -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() + "\"",

View file

@ -2,6 +2,7 @@ package validate
import (
"github.com/kyverno/go-wildcard"
"github.com/kyverno/policy-reporter/pkg/helper"
)

View file

@ -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")
}