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

Implement GCS target (#278)

* Implement GCS target

Signed-off-by: Frank Jogeleit <frank.jogeleit@web.de>
This commit is contained in:
Frank Jogeleit 2023-03-20 14:42:39 +01:00 committed by GitHub
parent fc46eeae76
commit db55835e53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 433 additions and 12 deletions

View file

@ -8,6 +8,9 @@
* optional API access logging with `api.logging` set to `true`
* New aggregation table for API performance improvements
* Helm Ingress template
* New Google Cloud Storage Target
* Requires `credentials` as JSON String and the `bucket` name
* Added in the helm valus under `target.gcs`
* Policy Reporter KyvernoPlugin
* Helm Ingress template

View file

@ -60,6 +60,7 @@ Policy Reporter supports the following [Targets](https://kyverno.github.io/polic
* [MS Teams](https://kyverno.github.io/policy-reporter/core/targets#microsoft-teams)
* [Policy Reporter UI](https://kyverno.github.io/policy-reporter/core/targets#policy-reporter-ui)
* [S3](https://kyverno.github.io/policy-reporter/core/targets#s3-compatible-storage)
* Google Cloud Storage
## Monitoring

View file

@ -208,6 +208,30 @@ kinesis:
{{- toYaml . | nindent 4 }}
{{- end }}
gcs:
credentials: {{ .Values.target.gcs.credentials }}
secretRef: {{ .Values.target.gcs.secretRef | quote }}
bucket: {{ .Values.target.gcs.bucket }}
prefix: {{ .Values.target.gcs.prefix }}
minimumPriority: {{ .Values.target.gcs.minimumPriority | quote }}
skipExistingOnStartup: {{ .Values.target.gcs.skipExistingOnStartup }}
{{- with .Values.target.gcs.sources }}
sources:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.target.gcs.customFields }}
customFields:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.target.gcs.filter }}
filter:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.target.gcs.channels }}
channels:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.policyPriorities }}
priorityMap:
{{- toYaml . | nindent 2 }}

View file

@ -502,6 +502,26 @@ target:
# add additional s3 channels with different configurations and filters
channels: []
gcs:
# GCS (Google Cloud Storage) Service Accout Credentials
credentials: ""
# receive the credentials from an existing secret instead
secretRef: ""
# GCS Bucket
bucket: ""
# minimum priority "" < info < warning < critical < error
minimumPriority: ""
# list of sources which should send to GCS
sources: []
# Skip already existing PolicyReportResults on startup
skipExistingOnStartup: true
# Added as additional properties to each gcs event
customFields: {}
# filter results send by namespaces, policies and priorities
filter: {}
# add additional s3 channels with different configurations and filters
channels: []
# required when policy-reporter runs in HA mode and you have targets configured
# if no targets are configured, leaderElection is disabled automatically
# will be enabled when replicaCount > 1

15
go.mod
View file

@ -3,6 +3,7 @@ module github.com/kyverno/policy-reporter
go 1.19
require (
cloud.google.com/go/storage v1.30.0
github.com/aws/aws-sdk-go v1.44.222
github.com/go-redis/redis/v8 v8.11.5
github.com/kyverno/go-wildcard v1.0.5
@ -16,11 +17,16 @@ require (
github.com/xhit/go-simple-mail/v2 v2.13.0
go.uber.org/zap v1.24.0
golang.org/x/sync v0.1.0
google.golang.org/api v0.114.0
k8s.io/apimachinery v0.26.2
k8s.io/client-go v0.26.2
)
require (
cloud.google.com/go v0.110.0 // indirect
cloud.google.com/go/compute v1.18.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@ -32,10 +38,13 @@ require (
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
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
@ -57,11 +66,15 @@ require (
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
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
@ -80,7 +93,7 @@ require (
github.com/prometheus/common v0.42.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.6.0 // indirect
golang.org/x/oauth2 v0.6.0
golang.org/x/term v0.6.0 // indirect
golang.org/x/time v0.3.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect

38
go.sum
View file

@ -17,14 +17,23 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@ -35,13 +44,13 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cloud.google.com/go/storage v1.30.0 h1:g1yrbxAWOrvg/594228pETWkOi00MLTrOWfh56veU5o=
cloud.google.com/go/storage v1.30.0/go.mod h1:xAVretHSROm1BQX4IIsoVgJqw0LqOyX+I/O2GzRAzdE=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
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/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/aws/aws-sdk-go v1.44.220 h1:yAj99qAt0Htjle9Up3DglgHfOP77lmFPrElA4jKnrBo=
github.com/aws/aws-sdk-go v1.44.220/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.222 h1:hagcC+MrGo60DKEbX0g6/ge4pIj7vBbsIb+vrhA/54I=
github.com/aws/aws-sdk-go v1.44.222/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
@ -49,7 +58,6 @@ 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 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -108,6 +116,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@ -145,6 +154,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
@ -152,9 +162,11 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@ -169,8 +181,12 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -179,8 +195,6 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/imdario/mergo v0.3.14 h1:fOqeC1+nCuuk6PKQdg9YmosXX7Y7mHX6R/0ZldI9iHo=
github.com/imdario/mergo v0.3.14/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@ -302,6 +316,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
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.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@ -380,6 +396,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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=
@ -533,6 +550,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@ -552,6 +571,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -598,6 +619,8 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -617,6 +640,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -630,8 +655,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM=
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -652,7 +675,6 @@ 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=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -164,6 +164,21 @@ type Kinesis struct {
Channels []Kinesis `mapstructure:"channels"`
}
// GCS configuration
type GCS struct {
Name string `mapstructure:"name"`
Credentials string `mapstructure:"credentials"`
Prefix string `mapstructure:"prefix"`
Bucket string `mapstructure:"bucket"`
SecretRef string `mapstructure:"secretRef"`
CustomFields map[string]string `mapstructure:"customFields"`
SkipExisting bool `mapstructure:"skipExistingOnStartup"`
MinimumPriority string `mapstructure:"minimumPriority"`
Filter TargetFilter `mapstructure:"filter"`
Sources []string `mapstructure:"sources"`
Channels []GCS `mapstructure:"channels"`
}
// SMTP configuration
type SMTP struct {
Host string `mapstructure:"host"`
@ -279,6 +294,7 @@ type Config struct {
Teams Teams `mapstructure:"teams"`
S3 S3 `mapstructure:"s3"`
Kinesis Kinesis `mapstructure:"kinesis"`
GCS GCS `mapstructure:"gcs"`
UI UI `mapstructure:"ui"`
Webhook Webhook `mapstructure:"webhook"`
API API `mapstructure:"api"`

View file

@ -213,6 +213,7 @@ func (r *Resolver) TargetClients() []target.Client {
clients = append(clients, factory.S3Clients(r.config.S3)...)
clients = append(clients, factory.KinesisClients(r.config.Kinesis)...)
clients = append(clients, factory.WebhookClients(r.config.Webhook)...)
clients = append(clients, factory.GCSClients(r.config.GCS)...)
if ui := factory.UIClient(r.config.UI); ui != nil {
clients = append(clients, ui)

View file

@ -104,6 +104,15 @@ var testConfig = &config.Config{
CustomFields: map[string]string{"field": "value"},
Channels: []config.Kinesis{{}},
},
GCS: config.GCS{
Credentials: "Credentials",
Bucket: "test",
SkipExisting: true,
MinimumPriority: "debug",
Prefix: "prefix",
CustomFields: map[string]string{"field": "value"},
Channels: []config.GCS{{}},
},
EmailReports: config.EmailReports{
Templates: config.EmailTemplates{
Dir: "../../templates",
@ -122,7 +131,7 @@ var testConfig = &config.Config{
func Test_ResolveTargets(t *testing.T) {
resolver := config.NewResolver(testConfig, &rest.Config{})
if count := len(resolver.TargetClients()); count != 17 {
if count := len(resolver.TargetClients()); count != 19 {
t.Errorf("Expected 17 Clients, got %d", count)
}
}

View file

@ -13,6 +13,7 @@ import (
"github.com/kyverno/policy-reporter/pkg/target"
"github.com/kyverno/policy-reporter/pkg/target/discord"
"github.com/kyverno/policy-reporter/pkg/target/elasticsearch"
"github.com/kyverno/policy-reporter/pkg/target/gcs"
"github.com/kyverno/policy-reporter/pkg/target/http"
"github.com/kyverno/policy-reporter/pkg/target/kinesis"
"github.com/kyverno/policy-reporter/pkg/target/loki"
@ -235,6 +236,29 @@ func (f *TargetFactory) KinesisClients(config Kinesis) []target.Client {
return clients
}
// S3Clients resolver method
func (f *TargetFactory) GCSClients(config GCS) []target.Client {
clients := make([]target.Client, 0)
if config.Name == "" {
config.Name = "Google Cloud Storage"
}
if es := f.createGCSClient(config, GCS{}); es != nil {
clients = append(clients, es)
}
for i, channel := range config.Channels {
if channel.Name == "" {
channel.Name = fmt.Sprintf("GCS Channel %d", i+1)
}
if es := f.createGCSClient(channel, config); es != nil {
clients = append(clients, es)
}
}
return clients
}
func (f *TargetFactory) createSlackClient(config Slack, parent Slack) target.Client {
if config.SecretRef != "" && f.secretClient != nil {
f.mapSecretValues(&config, config.SecretRef)
@ -658,6 +682,61 @@ func (f *TargetFactory) createKinesisClient(config Kinesis, parent Kinesis) targ
})
}
func (f *TargetFactory) createGCSClient(config GCS, parent GCS) target.Client {
if config.SecretRef != "" && f.secretClient != nil {
f.mapSecretValues(&config, config.SecretRef)
}
if config.Bucket == "" && parent.Bucket == "" {
return nil
} else if config.Bucket == "" {
config.Bucket = parent.Bucket
}
sugar := zap.S()
if config.Credentials == "" && parent.Credentials == "" {
sugar.Errorf("%s.Credentials has not been declared", config.Name)
return nil
} else if config.Credentials == "" {
config.Credentials = parent.Credentials
}
if config.Prefix == "" && parent.Prefix == "" {
config.Prefix = "policy-reporter"
} else if config.Prefix == "" {
config.Prefix = parent.Prefix
}
if config.MinimumPriority == "" {
config.MinimumPriority = parent.MinimumPriority
}
if !config.SkipExisting {
config.SkipExisting = parent.SkipExisting
}
gcsClient := helper.NewGCSClient(
context.Background(),
config.Credentials,
config.Bucket,
)
sugar.Infof("%s configured", config.Name)
return gcs.NewClient(gcs.Options{
ClientOptions: target.ClientOptions{
Name: config.Name,
SkipExistingOnStartup: config.SkipExisting,
ResultFilter: createResultFilter(config.Filter, config.MinimumPriority, config.Sources),
ReportFilter: createReprotFilter(config.Filter),
},
Client: gcsClient,
CustomFields: config.CustomFields,
Prefix: config.Prefix,
})
}
func (f *TargetFactory) mapSecretValues(config any, ref string) {
values, err := f.secretClient.Get(context.Background(), ref)
if err != nil {
@ -713,6 +792,11 @@ func (f *TargetFactory) mapSecretValues(config any, ref string) {
c.SecretAccessKey = values.SecretAccessKey
}
case *GCS:
if values.Credentials != "" {
c.Credentials = values.Credentials
}
case *Webhook:
if values.Host != "" {
c.Host = values.Host

View file

@ -30,6 +30,7 @@ func newFakeClient() v1.SecretInterface {
"accessKeyID": []byte("accessKeyID"),
"secretAccessKey": []byte("secretAccessKey"),
"token": []byte("token"),
"credentials": []byte("credentials"),
},
}).CoreV1().Secrets("default")
}
@ -81,6 +82,12 @@ func Test_ResolveTarget(t *testing.T) {
t.Errorf("Expected 2 Client, got %d clients", len(clients))
}
})
t.Run("GCS", func(t *testing.T) {
clients := factory.GCSClients(testConfig.GCS)
if len(clients) != 2 {
t.Errorf("Expected 2 Client, got %d clients", len(clients))
}
})
t.Run("Kinesis", func(t *testing.T) {
clients := factory.KinesisClients(testConfig.Kinesis)
if len(clients) != 2 {
@ -172,6 +179,16 @@ func Test_ResolveTargetWithoutHost(t *testing.T) {
t.Error("Expected Client to be nil if no bucket is configured")
}
})
t.Run("GCS.Bucket", func(t *testing.T) {
if len(factory.GCSClients(config.GCS{})) != 0 {
t.Error("Expected Client to be nil if no bucket is configured")
}
})
t.Run("GCS.Credentials", func(t *testing.T) {
if len(factory.GCSClients(config.GCS{Bucket: "policy-reporter"})) != 0 {
t.Error("Expected Client to be nil if no accessKey is configured")
}
})
}
func Test_GetValuesFromSecret(t *testing.T) {
@ -283,6 +300,13 @@ func Test_GetValuesFromSecret(t *testing.T) {
}
})
t.Run("Get GCS values from Secret", func(t *testing.T) {
clients := factory.GCSClients(config.GCS{SecretRef: secretName, Bucket: "bucket"})
if len(clients) != 1 {
t.Error("Expected one client created")
}
})
t.Run("Get none existing secret skips target", func(t *testing.T) {
clients := factory.LokiClients(config.Loki{SecretRef: "no-exist"})
if len(clients) != 0 {
@ -394,4 +418,17 @@ func Test_GetValuesFromSecret(t *testing.T) {
t.Errorf("Expected customLabels are added")
}
})
t.Run("Get CustomFields from GCS", func(t *testing.T) {
clients := factory.GCSClients(testConfig.GCS)
if len(clients) < 1 {
t.Error("Expected one client created")
}
client := reflect.ValueOf(clients[0]).Elem()
customFields := client.FieldByName("customFields").MapKeys()
if customFields[0].String() != "field" {
t.Errorf("Expected customFields are added")
}
})
}

50
pkg/helper/gcp.go Normal file
View file

@ -0,0 +1,50 @@
package helper
import (
"bytes"
"context"
"cloud.google.com/go/storage"
"go.uber.org/zap"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"
)
type GCPClient interface {
// Upload given Data the configured AWS storage
Upload(body *bytes.Buffer, key string) error
}
type gcsClient struct {
bucket string
client *storage.Client
}
func (c *gcsClient) Upload(body *bytes.Buffer, key string) error {
writer := c.client.Bucket(c.bucket).Object(key).NewWriter(context.Background())
defer writer.Close()
_, err := writer.Write(body.Bytes())
return err
}
// NewS3Client creates a new S3.client to send Results to S3
func NewGCSClient(ctx context.Context, credentials, bucket string) GCPClient {
cred, err := google.CredentialsFromJSON(ctx, []byte(credentials))
if err != nil {
zap.L().Error("error while creating GCS credentials")
return nil
}
client, err := storage.NewClient(ctx, option.WithCredentials(cred))
if err != nil {
zap.L().Error("error while creating GCS client")
return nil
}
return &gcsClient{
bucket,
client,
}
}

View file

@ -15,6 +15,7 @@ type Values struct {
AccessKeyID string
SecretAccessKey string
Token string
Credentials string
}
type Client interface {
@ -60,6 +61,10 @@ func (c *k8sClient) Get(ctx context.Context, name string) (Values, error) {
values.Token = string(token)
}
if token, ok := secret.Data["credentials"]; ok {
values.Credentials = string(token)
}
return values, nil
}

73
pkg/target/gcs/gcs.go Normal file
View file

@ -0,0 +1,73 @@
package gcs
import (
"bytes"
"encoding/json"
"fmt"
"time"
"go.uber.org/zap"
"github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2"
"github.com/kyverno/policy-reporter/pkg/helper"
"github.com/kyverno/policy-reporter/pkg/target"
"github.com/kyverno/policy-reporter/pkg/target/http"
)
// Options to configure the GCS target
type Options struct {
target.ClientOptions
CustomFields map[string]string
Client helper.GCPClient
Prefix string
}
type client struct {
target.BaseClient
customFields map[string]string
client helper.GCPClient
prefix string
}
func (c *client) Send(result v1alpha2.PolicyReportResult) {
if len(c.customFields) > 0 {
props := make(map[string]string, 0)
for property, value := range c.customFields {
props[property] = value
}
for property, value := range result.Properties {
props[property] = value
}
result.Properties = props
}
body := new(bytes.Buffer)
if err := json.NewEncoder(body).Encode(http.NewJSONResult(result)); err != nil {
zap.L().Error(c.Name()+": encode error", zap.Error(err))
return
}
t := time.Unix(result.Timestamp.Seconds, int64(result.Timestamp.Nanos))
key := fmt.Sprintf("%s/%s/%s-%s-%s.json", c.prefix, t.Format("2006-01-02"), result.Policy, result.ID, t.Format(time.RFC3339Nano))
err := c.client.Upload(body, key)
if err != nil {
zap.L().Error(c.Name()+": Upload error", zap.Error(err))
return
}
zap.L().Info(c.Name() + ": PUSH OK")
}
// NewClient creates a new GCS.client to send Results to Google Cloud Storage.
func NewClient(options Options) target.Client {
return &client{
target.NewBaseClient(options.ClientOptions),
options.CustomFields,
options.Client,
options.Prefix,
}
}

View file

@ -0,0 +1,63 @@
package gcs_test
import (
"bytes"
"encoding/json"
"testing"
"github.com/kyverno/policy-reporter/pkg/fixtures"
"github.com/kyverno/policy-reporter/pkg/target"
"github.com/kyverno/policy-reporter/pkg/target/gcs"
)
type testClient struct {
err error
callback func(body *bytes.Buffer, key string)
}
func (c *testClient) Upload(_ *bytes.Buffer, _ string) error {
return c.err
}
var testCallback = func(body *bytes.Buffer, key string) {}
func Test_GCSTarget(t *testing.T) {
t.Run("Send", func(t *testing.T) {
callback := func(body *bytes.Buffer, key string) {
report := new(bytes.Buffer)
json.NewEncoder(report).Encode(fixtures.CompleteTargetSendResult)
if body != report {
buf := new(bytes.Buffer)
buf.ReadFrom(body)
t.Errorf("Unexpected Body Content: %s", buf.String())
}
}
client := gcs.NewClient(gcs.Options{
ClientOptions: target.ClientOptions{
Name: "GCS",
},
CustomFields: map[string]string{"cluster": "name"},
Client: &testClient{nil, callback},
})
client.Send(fixtures.CompleteTargetSendResult)
if len(fixtures.CompleteTargetSendResult.Properties) > 1 || fixtures.CompleteTargetSendResult.Properties["cluster"] != "" {
t.Error("expected customFields are not added to the actuel result")
}
})
t.Run("Name", func(t *testing.T) {
client := gcs.NewClient(gcs.Options{
ClientOptions: target.ClientOptions{
Name: "GCS",
},
Client: &testClient{},
})
if client.Name() != "GCS" {
t.Errorf("Unexpected Name %s", client.Name())
}
})
}

View file

@ -14,7 +14,7 @@ import (
"github.com/kyverno/policy-reporter/pkg/target/http"
)
// Options to configure the Kinesis target
// Options to configure the S3 target
type Options struct {
target.ClientOptions
CustomFields map[string]string
@ -62,7 +62,7 @@ func (c *client) Send(result v1alpha2.PolicyReportResult) {
zap.L().Info(c.Name() + ": PUSH OK")
}
// NewClient creates a new S3.client to send Results to S3. It doesnt' work right now
// NewClient creates a new S3.client to send Results to S3.
func NewClient(options Options) target.Client {
return &client{
target.NewBaseClient(options.ClientOptions),