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:
parent
fc46eeae76
commit
db55835e53
16 changed files with 433 additions and 12 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }}
|
||||
|
|
|
@ -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
15
go.mod
|
@ -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
38
go.sum
|
@ -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=
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
50
pkg/helper/gcp.go
Normal 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,
|
||||
}
|
||||
}
|
|
@ -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
73
pkg/target/gcs/gcs.go
Normal 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,
|
||||
}
|
||||
}
|
63
pkg/target/gcs/gcs_test.go
Normal file
63
pkg/target/gcs/gcs_test.go
Normal 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())
|
||||
}
|
||||
})
|
||||
}
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue