mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
Implement global anchor (#2311)
* implement global anchor for patch strategic merge
Signed-off-by: Max Goncharenko <kacejot@fex.net>
* fixed unit tests for mutation global anchor
Signed-off-by: Max Goncharenko <kacejot@fex.net>
* added global anchor in validation
Signed-off-by: Max Goncharenko <kacejot@fex.net>
* fix some global anchor issues found during testing
Signed-off-by: Max Goncharenko <kacejot@fex.net>
* run go tidy
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
* fixed tests
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
* fixed some tests
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
* finish implementing global anchor
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
* WIP: lower global anchor strictness
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
* Revert "WIP: lower global anchor strictness"
This reverts commit 08e176a042
.
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
* global anchor for mutation
Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
This commit is contained in:
parent
f6933bb439
commit
a0ff8bbd0b
17 changed files with 551 additions and 222 deletions
8
go.mod
8
go.mod
|
@ -17,6 +17,7 @@ require (
|
|||
github.com/google/go-containerregistry v0.6.0
|
||||
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20210216200643-d81088d9983e
|
||||
github.com/googleapis/gnostic v0.5.4
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/kataras/tablewriter v0.0.0-20180708051242-e063d29b7c23
|
||||
|
@ -24,6 +25,7 @@ require (
|
|||
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a
|
||||
github.com/minio/minio v0.0.0-20200114012931-30922148fbb5
|
||||
github.com/minio/pkg v1.0.7
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/onsi/ginkgo v1.15.0
|
||||
github.com/onsi/gomega v1.11.0
|
||||
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
|
||||
|
@ -31,10 +33,12 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/sigstore/cosign v1.1.0
|
||||
github.com/sigstore/sigstore v0.0.0-20210729211320-56a91f560f44
|
||||
github.com/sigstore/cosign v1.0.0
|
||||
github.com/sigstore/rekor v0.3.0 // indirect
|
||||
github.com/sigstore/sigstore v0.0.0-20210726180807-7e34e36ecda1
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
gotest.tools v2.2.0+incompatible
|
||||
|
|
68
go.sum
68
go.sum
|
@ -28,9 +28,8 @@ cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E
|
|||
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
|
||||
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
|
||||
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
|
||||
cloud.google.com/go v0.88.0 h1:MZ2cf9Elnv1wqccq8ooKO2MqHQLc+ChCp/+QWObCpxg=
|
||||
cloud.google.com/go v0.88.0/go.mod h1:dnKwfYbP9hQhefiUvpbcAyoGSHUrOxR20JVElLiUvEY=
|
||||
cloud.google.com/go v0.90.0 h1:MjvSkUq8RuAb+2JLDi5VQmmExRJPUQ3JLCWpRB6fmdw=
|
||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||
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=
|
||||
|
@ -55,7 +54,6 @@ 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.15.0/go.mod h1:mjjQMoxxyGH7Jr8K5qrx6N2O0AHsczI61sMNn03GIZI=
|
||||
cloud.google.com/go/storage v1.16.0 h1:1UwAux2OZP4310YXg5ohqBEpV16Y93uZG4+qOX7K2Kg=
|
||||
cloud.google.com/go/storage v1.16.0/go.mod h1:ieKBmUyzcftN5tbxwnXClMKH00CfcQ+xL6NN0r5QfmE=
|
||||
code.gitea.io/sdk/gitea v0.11.3/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
||||
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
|
||||
|
@ -79,6 +77,7 @@ github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo
|
|||
github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v54.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v55.7.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v55.8.0+incompatible h1:EuccMPzxu67cIE95/mrtwQivLv7ETmURi5IUgLNVug8=
|
||||
github.com/Azure/azure-sdk-for-go v55.8.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0=
|
||||
|
@ -109,8 +108,9 @@ github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQW
|
|||
github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.14 h1:G8hexQdV5D4khOXrWG2YuLCFKhWYmWD8bHYaXN5ophk=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM=
|
||||
|
@ -163,6 +163,7 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
|
|||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
|
||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
|
@ -256,6 +257,7 @@ github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/
|
|||
github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.39.6/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.40.4/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.40.7 h1:dD5+UZxedqHeE4WakJHEhTsEARYlq8kHkYEf89R1tEo=
|
||||
github.com/aws/aws-sdk-go v1.40.7/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
|
@ -299,6 +301,7 @@ github.com/cavaliercoder/go-rpm v0.0.0-20200122174316-8cb9fd9c31a8/go.mod h1:AZI
|
|||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
|
@ -454,9 +457,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
|
|||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4 h1:7AjYfmq7AmviXsuZjV5DcE7PuhJ4dWMi8gLllpLVDQY=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b h1:lMzA7yYThpwx7iYNpTeiQnRH6h5JSfSYMJdz+pxZOW8=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
|
@ -871,15 +873,14 @@ github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwG
|
|||
github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.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/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE=
|
||||
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+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.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
|
||||
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
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=
|
||||
|
@ -896,7 +897,6 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
|
||||
github.com/google/rpmpack v0.0.0-20210518075352-dc539ef4f2ea/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk=
|
||||
|
@ -949,8 +949,9 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
|
|||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
|
@ -1083,7 +1084,6 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
|
|||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
|
@ -1316,8 +1316,9 @@ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/
|
|||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
|
||||
github.com/nsqio/go-nsq v1.0.7/go.mod h1:XP5zaUs3pqf+Q71EqUJs3HYfBIqfK6G83WQMdNN+Ito=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
|
@ -1352,7 +1353,7 @@ github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDs
|
|||
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/open-policy-agent/opa v0.31.0/go.mod h1:aeLYiWaZe9ikcX67qLzmtRTOxj7psNYh6YGTbTW6V+s=
|
||||
github.com/open-policy-agent/opa v0.30.2/go.mod h1:+Bv1G/E7Irxgm5zLNXiHuxYqMaqJUSKyBhIGxeneoGA=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
|
@ -1462,6 +1463,7 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+
|
|||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.29.0 h1:3jqPBvKT4OHAbje2Ql7KeaaSicDBCxMYwEJU1zRJceE=
|
||||
|
@ -1532,14 +1534,16 @@ github.com/shibumi/go-pathspec v1.2.0/go.mod h1:bDxCftD0fST3qXIlHoQ/fChsU4mWMVkl
|
|||
github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil/v3 v3.21.4/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sigstore/cosign v1.1.0 h1:fvoQAyR3N7GmRhE/Le02eo9qBWau0784wcIk7EjLJGQ=
|
||||
github.com/sigstore/cosign v1.1.0/go.mod h1:L7DOTaKaaWG+EOB9IKk6g8CZqwawrmeMVukXFJPevzs=
|
||||
github.com/sigstore/cosign v1.0.0 h1:jvsRP8ZfEc5jAnj2cGQo5S02VQ7h7rXwpiXYJF4n0+0=
|
||||
github.com/sigstore/cosign v1.0.0/go.mod h1:XdYJiB4fkKo+OepAHtDgWU6n1MpP08eM8H2rIr5QU4U=
|
||||
github.com/sigstore/fulcio v0.1.1/go.mod h1:HAsi0o0xMmBIauM9QkJ4dyvmeEzK1ZGcmH33gQ6xO3c=
|
||||
github.com/sigstore/rekor v0.2.1-0.20210714185543-38d532d5c0b1/go.mod h1:cL9B3+/gp3BG+/bhkSHBA3MQZMten5xM6BhJYd5b5zU=
|
||||
github.com/sigstore/rekor v0.3.0 h1:OBEvo/Rv8NKKtiWq0WRHgXFpVPe1fGiqz93dfBh/Myo=
|
||||
github.com/sigstore/rekor v0.3.0/go.mod h1:cL9B3+/gp3BG+/bhkSHBA3MQZMten5xM6BhJYd5b5zU=
|
||||
github.com/sigstore/sigstore v0.0.0-20210713222344-1fee53516622/go.mod h1:aOSeNrlcHsfUD8Q1hwWd8KloNqBnxEZlu4k47cFg5rg=
|
||||
github.com/sigstore/sigstore v0.0.0-20210729211320-56a91f560f44 h1:V7tcgdv69z2dAn31YzOjc6tGuZHpjC3kcpYT+XJmw4s=
|
||||
github.com/sigstore/sigstore v0.0.0-20210729211320-56a91f560f44/go.mod h1:rJpRn7XmR/YrfNGDU9jh+vy5WMeSv5YKfNDBwnFg+Qg=
|
||||
github.com/sigstore/sigstore v0.0.0-20210722023421-fd3b69438dba/go.mod h1:p+VFprG1w+oRcb3fgEKa9uvw3/7N9TR0srIi2JerPKo=
|
||||
github.com/sigstore/sigstore v0.0.0-20210726180807-7e34e36ecda1 h1:4pct+K5MTh3G4AbiSjYpYT3MVVI5WdDdJZEr9bTkLb8=
|
||||
github.com/sigstore/sigstore v0.0.0-20210726180807-7e34e36ecda1/go.mod h1:/za/jqA/1XazvjIfvvtDkIAJZWKqkbcT5VTpHR7hnfQ=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
|
@ -1627,16 +1631,13 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
|
|||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 h1:iGnD/q9160NWqKZZ5vY4p0dMiYMRknzctfSkqA4nBDw=
|
||||
github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613/go.mod h1:g6AnIpDSYMcphz193otpSIzN+11Rs+AAIIC6rm1enug=
|
||||
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
|
||||
github.com/theupdateframework/go-tuf v0.0.0-20210630170422-22a94818d17b/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw=
|
||||
github.com/theupdateframework/go-tuf v0.0.0-20210722233521-90e262754396 h1:j4odVZMwglHp54CYsNHd0wls+lkQzxloQU9AQjQu0W4=
|
||||
github.com/theupdateframework/go-tuf v0.0.0-20210722233521-90e262754396/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw=
|
||||
github.com/theupdateframework/go-tuf v0.0.0-20210804171843-477a5d73800a h1:jH3DSl+6QKbX+koCvBf3cP+1mLRANxk36/hUtvA6HVg=
|
||||
github.com/theupdateframework/go-tuf v0.0.0-20210804171843-477a5d73800a/go.mod h1:aDPMGsrpdPQqJa0ryp7LovT6qSqZ/zKmUDTHZK+wIf4=
|
||||
github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
|
@ -1689,8 +1690,9 @@ github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59b
|
|||
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
|
@ -1975,8 +1977,9 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff h1:j2EK/QoxYNBsXI4R7fQkkRUk8y6wnOBI+6hgPdP/6Ds=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1996,9 +1999,8 @@ golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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-20210615190721-d04028783cf1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 h1:3B43BWw0xEBsLZ/NO1VALz6fppU3481pik+2Ksv45z8=
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a h1:4Kd8OPUx1xgUwrHDaviWZO8MsgoZTZYC3g+8m16RBww=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
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=
|
||||
|
@ -2302,9 +2304,8 @@ google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4yl
|
|||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
||||
google.golang.org/api v0.49.0/go.mod h1:BECiH72wsfwUvOVn3+btPD5WHi0LzavZReBndi42L18=
|
||||
google.golang.org/api v0.50.0 h1:LX7NFCFYOHzr7WHaYiRUpeipZe9o5L8T+2F4Z798VDw=
|
||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
||||
google.golang.org/api v0.51.0 h1:SQaA2Cx57B+iPw2MBgyjEkoeMkRK2IenSGoia0U3lCk=
|
||||
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -2388,12 +2389,10 @@ google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+n
|
|||
google.golang.org/genproto v0.0.0-20210624174822-c5cf32407d0a/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
|
||||
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
|
||||
google.golang.org/genproto v0.0.0-20210719143636-1d5a45f8e492/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f h1:YORWxaStkWBnWgELOHTmDrqNlFXuVGEbhwbB5iK94bQ=
|
||||
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67 h1:VmMSf20ssFK0+u1dscyTH9bU4/M4y+X/xNfkvD6kGtM=
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
|
@ -2427,9 +2426,8 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
|
|||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI=
|
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.39.1 h1:f37vZbBVTiJ6jKG5mWz8ySOBxNqy6ViPgyhSdVnxF3E=
|
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
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=
|
||||
|
@ -2535,7 +2533,6 @@ k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
|||
k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
|
||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||
k8s.io/api v0.20.7/go.mod h1:4x0yErUkcEWYG+O0S4QdrYa2+PLEeY2M7aeQe++2nmk=
|
||||
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
|
||||
k8s.io/api v0.21.3 h1:cblWILbLO8ar+Fj6xdDGr603HRsf8Wu9E9rngJeprZQ=
|
||||
k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
|
||||
|
@ -2551,7 +2548,6 @@ k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp
|
|||
k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apimachinery v0.20.7/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apimachinery v0.21.3 h1:3Ju4nvjCngxxMYby0BimUk+pQHPOQp3eCGChk5kfVII=
|
||||
k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI=
|
||||
|
|
|
@ -22,6 +22,8 @@ func CreateElementHandler(element string, pattern interface{}, path string) Vali
|
|||
switch {
|
||||
case commonAnchors.IsConditionAnchor(element):
|
||||
return NewConditionAnchorHandler(element, pattern, path)
|
||||
case commonAnchors.IsGlobalAnchor(element):
|
||||
return NewGlobalAnchorHandler(element, pattern, path)
|
||||
case commonAnchors.IsExistenceAnchor(element):
|
||||
return NewExistenceHandler(element, pattern, path)
|
||||
case commonAnchors.IsEqualityAnchor(element):
|
||||
|
@ -151,7 +153,8 @@ func (ch ConditionAnchorHandler) Handle(handler resourceElementHandler, resource
|
|||
// validate the values of the pattern
|
||||
returnPath, err := handler(log.Log, value, ch.pattern, originPattern, currentPath, ac)
|
||||
if err != nil {
|
||||
return returnPath, err
|
||||
ac.AnchorError = common.NewConditionalAnchorError(fmt.Sprintf("condition anchor did not satisfy: %s", err.Error()))
|
||||
return returnPath, ac.AnchorError.Error()
|
||||
}
|
||||
return "", nil
|
||||
|
||||
|
@ -159,6 +162,39 @@ func (ch ConditionAnchorHandler) Handle(handler resourceElementHandler, resource
|
|||
return "", nil
|
||||
}
|
||||
|
||||
//NewGlobalAnchorHandler returns an instance of condition acnhor handler
|
||||
func NewGlobalAnchorHandler(anchor string, pattern interface{}, path string) ValidationHandler {
|
||||
return GlobalAnchorHandler{
|
||||
anchor: anchor,
|
||||
pattern: pattern,
|
||||
path: path,
|
||||
}
|
||||
}
|
||||
|
||||
//GlobalAnchorHandler provides handler for global condition anchor
|
||||
type GlobalAnchorHandler struct {
|
||||
anchor string
|
||||
pattern interface{}
|
||||
path string
|
||||
}
|
||||
|
||||
//Handle processed global condition anchor
|
||||
func (gh GlobalAnchorHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *common.AnchorKey) (string, error) {
|
||||
anchorKey, _ := commonAnchors.RemoveAnchor(gh.anchor)
|
||||
currentPath := gh.path + anchorKey + "/"
|
||||
// check if anchor is present in resource
|
||||
if value, ok := resourceMap[anchorKey]; ok {
|
||||
// validate the values of the pattern
|
||||
returnPath, err := handler(log.Log, value, gh.pattern, originPattern, currentPath, ac)
|
||||
if err != nil {
|
||||
ac.AnchorError = common.NewGlobalAnchorError(fmt.Sprintf("global anchor did not satisfy: %s", err.Error()))
|
||||
return returnPath, ac.AnchorError.Error()
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
//NewExistenceHandler returns existence handler
|
||||
func NewExistenceHandler(anchor string, pattern interface{}, path string) ValidationHandler {
|
||||
return ExistenceHandler{
|
||||
|
|
|
@ -17,6 +17,24 @@ func IsConditionAnchor(str string) bool {
|
|||
return (str[0] == '(' && str[len(str)-1] == ')')
|
||||
}
|
||||
|
||||
//IsGlobalAnchor checks for global condition anchor
|
||||
func IsGlobalAnchor(str string) bool {
|
||||
left := "<("
|
||||
right := ")"
|
||||
if len(str) < len(left)+len(right) {
|
||||
return false
|
||||
}
|
||||
|
||||
//TODO: trim spaces ?
|
||||
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
|
||||
}
|
||||
|
||||
//ContainsCondition returns true, if str is either condition anchor or
|
||||
// global condition anchor
|
||||
func ContainsCondition(str string) bool {
|
||||
return IsConditionAnchor(str) || IsGlobalAnchor(str)
|
||||
}
|
||||
|
||||
//IsNegationAnchor checks for negation anchor
|
||||
func IsNegationAnchor(str string) bool {
|
||||
left := "X("
|
||||
|
@ -76,7 +94,7 @@ func RemoveAnchor(key string) (string, string) {
|
|||
return key[1 : len(key)-1], key[0:1]
|
||||
}
|
||||
|
||||
if IsExistenceAnchor(key) || IsAddingAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) {
|
||||
if IsExistenceAnchor(key) || IsAddingAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) || IsGlobalAnchor(key) {
|
||||
return key[2 : len(key)-1], key[0:2]
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@ func IsConditionalAnchorError(msg string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsGlobalAnchorError checks if error message has conditional anchor error string
|
||||
func IsGlobalAnchorError(msg string) bool {
|
||||
return strings.Contains(msg, GlobalAnchorErrMsg)
|
||||
}
|
||||
|
||||
// NewConditionalAnchorError returns a new instance of ConditionalAnchorError
|
||||
func NewConditionalAnchorError(msg string) ValidateAnchorError {
|
||||
return ValidateAnchorError{
|
||||
|
@ -26,10 +31,20 @@ func NewConditionalAnchorError(msg string) ValidateAnchorError {
|
|||
|
||||
// IsConditionAnchorError ...
|
||||
func (e ValidateAnchorError) IsConditionAnchorError() bool {
|
||||
if e.Err == ConditionalAnchorErr {
|
||||
return true
|
||||
return e.Err == ConditionalAnchorErr
|
||||
}
|
||||
|
||||
// NewGlobalAnchorError returns a new instance of GlobalAnchorError
|
||||
func NewGlobalAnchorError(msg string) ValidateAnchorError {
|
||||
return ValidateAnchorError{
|
||||
Err: GlobalAnchorErr,
|
||||
Message: fmt.Sprintf("%s: %s", GlobalAnchorErrMsg, msg),
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsConditionAnchorError ...
|
||||
func (e ValidateAnchorError) IsGlobalAnchorError() bool {
|
||||
return e.Err == GlobalAnchorErr
|
||||
}
|
||||
|
||||
// IsNil ...
|
||||
|
@ -44,8 +59,13 @@ func (e ValidateAnchorError) Error() error {
|
|||
// AnchorError is the const specification of anchor errors
|
||||
type AnchorError int
|
||||
|
||||
// ConditionalAnchorErr ...
|
||||
const ConditionalAnchorErr AnchorError = iota
|
||||
const (
|
||||
// ConditionalAnchorErr refers to condition violation
|
||||
ConditionalAnchorErr AnchorError = iota
|
||||
|
||||
// GlobalAnchorErr refers to global condition violation
|
||||
GlobalAnchorErr
|
||||
)
|
||||
|
||||
// ValidateAnchorError represents the error type of validation anchors
|
||||
type ValidateAnchorError struct {
|
||||
|
@ -56,6 +76,9 @@ type ValidateAnchorError struct {
|
|||
// ConditionalAnchorErrMsg - the error message for conditional anchor error
|
||||
var ConditionalAnchorErrMsg = "conditionalAnchorError"
|
||||
|
||||
// GlobalAnchorErrMsg - the error message for global anchor error
|
||||
var GlobalAnchorErrMsg = "globalAnchorError"
|
||||
|
||||
// AnchorKey - contains map of anchors
|
||||
type AnchorKey struct {
|
||||
// anchorMap - for each anchor key in the patterns it will maintains information if the key exists in the resource
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
@ -30,26 +29,6 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
|
|||
logger.V(4).Info("finished applying strategicMerge patch", "processingTime", resp.RuleStats.ProcessingTime.String())
|
||||
}()
|
||||
|
||||
// ====== Meet Conditions =======
|
||||
if path, overlayerr := meetConditions(log, resource.UnstructuredContent(), overlay); !reflect.DeepEqual(overlayerr, overlayError{}) {
|
||||
switch overlayerr.statusCode {
|
||||
// anchor key does not exist in the resource, skip applying policy
|
||||
case conditionNotPresent:
|
||||
log.V(4).Info("skip applying policy", "path", path, "error", overlayerr)
|
||||
log.V(3).Info("skip applying rule", "reason", "conditionNotPresent")
|
||||
resp.Success = true
|
||||
return resp, resource
|
||||
// anchor key is not satisfied in the resource, skip applying policy
|
||||
case conditionFailure:
|
||||
log.V(4).Info("failed to validate condition", "path", path, "error", overlayerr)
|
||||
log.V(3).Info("skip applying rule", "reason", "conditionFailure")
|
||||
resp.Success = true
|
||||
resp.Message = overlayerr.ErrorMsg()
|
||||
return resp, resource
|
||||
}
|
||||
}
|
||||
// ============================
|
||||
|
||||
overlayBytes, err := json.Marshal(overlay)
|
||||
if err != nil {
|
||||
resp.Success = false
|
||||
|
@ -99,14 +78,23 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
|
|||
|
||||
resp.Success = true
|
||||
resp.Patches = jsonPatches
|
||||
resp.Message = fmt.Sprintf("successfully processed strategic merge patch")
|
||||
resp.Message = "successfully processed strategic merge patch"
|
||||
return resp, patchedResource
|
||||
}
|
||||
|
||||
func strategicMergePatch(logger logr.Logger, base, overlay string) ([]byte, error) {
|
||||
preprocessedYaml, err := preProcessStrategicMergePatch(logger, overlay, base)
|
||||
if err != nil {
|
||||
return []byte{}, fmt.Errorf("failed to preProcess rule: %+v", err)
|
||||
_, isConditionError := err.(ConditionError)
|
||||
_, isGlobalConditionError := err.(GlobalConditionError)
|
||||
|
||||
if isConditionError || isGlobalConditionError {
|
||||
if err = preprocessedYaml.UnmarshalJSON([]byte(`{}`)); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
} else {
|
||||
return []byte{}, fmt.Errorf("failed to preProcess rule: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
f := patchstrategicmerge.Filter{
|
||||
|
@ -122,6 +110,8 @@ func strategicMergePatch(logger logr.Logger, base, overlay string) ([]byte, erro
|
|||
func preProcessStrategicMergePatch(logger logr.Logger, pattern, resource string) (*yaml.RNode, error) {
|
||||
patternNode := yaml.MustParse(pattern)
|
||||
resourceNode := yaml.MustParse(resource)
|
||||
|
||||
err := preProcessPattern(logger, patternNode, resourceNode)
|
||||
|
||||
return patternNode, err
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package mutate
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
|
@ -25,33 +24,149 @@ func TestMergePatch(t *testing.T) {
|
|||
},
|
||||
{
|
||||
// condition matches the first element of the array
|
||||
rawPolicy: []byte(`{"spec": {"containers": [{"(image)": "gcr.io/google-containers/busybox:*"}],"imagePullSecrets": [{"name": "regcred"}]}}`),
|
||||
rawResource: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "hello"},"spec": {"containers": [{"name": "hello","image": "gcr.io/google-containers/busybox:latest"},{"name": "hello2","image": "gcr.io/google-containers/busybox:latest"},{"name": "hello3","image": "gcr.io/google-containers/nginx:latest"}]}}`),
|
||||
expected: []byte(`{"apiVersion":"v1","kind":"Pod","metadata":{"name":"hello"},"spec":{"containers":[{"image":"gcr.io/google-containers/busybox:latest","name":"hello"},{"image":"gcr.io/google-containers/busybox:latest","name":"hello2"},{"image":"gcr.io/google-containers/nginx:latest","name":"hello3"}],"imagePullSecrets":[{"name":"regcred"}]}}`),
|
||||
rawPolicy: []byte(`{
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "gcr.io/google-containers/busybox:*"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
rawResource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "hello"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
},
|
||||
{
|
||||
"name": "hello2",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
},
|
||||
{
|
||||
"name": "hello3",
|
||||
"image": "gcr.io/google-containers/nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
expected: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "hello"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"image": "gcr.io/google-containers/busybox:latest",
|
||||
"name": "hello"
|
||||
},
|
||||
{
|
||||
"image": "gcr.io/google-containers/busybox:latest",
|
||||
"name": "hello2"
|
||||
},
|
||||
{
|
||||
"image": "gcr.io/google-containers/nginx:latest",
|
||||
"name": "hello3"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
},
|
||||
{
|
||||
// condition matches the third element of the array
|
||||
rawPolicy: []byte(`{"spec": {"containers": [{"(image)": "gcr.io/google-containers/nginx:*"}],"imagePullSecrets": [{"name": "regcred"}]}}`),
|
||||
rawResource: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "hello"},"spec": {"containers": [{"name": "hello","image": "gcr.io/google-containers/busybox:latest"},{"name": "hello2","image": "gcr.io/google-containers/busybox:latest"},{"name": "hello3","image": "gcr.io/google-containers/nginx:latest"}]}}`),
|
||||
expected: []byte(`{"apiVersion":"v1","kind":"Pod","metadata":{"name":"hello"},"spec":{"containers":[{"image":"gcr.io/google-containers/nginx:latest","name":"hello3"},{"image":"gcr.io/google-containers/busybox:latest","name":"hello"},{"image":"gcr.io/google-containers/busybox:latest","name":"hello2"}],"imagePullSecrets":[{"name":"regcred"}]}}`),
|
||||
rawPolicy: []byte(`{
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "gcr.io/google-containers/nginx:*"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
rawResource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "hello"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
},
|
||||
{
|
||||
"name": "hello2",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
},
|
||||
{
|
||||
"name": "hello3",
|
||||
"image": "gcr.io/google-containers/nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
expected: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "hello"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"image": "gcr.io/google-containers/busybox:latest",
|
||||
"name": "hello"
|
||||
},
|
||||
{
|
||||
"image": "gcr.io/google-containers/busybox:latest",
|
||||
"name": "hello2"
|
||||
},
|
||||
{
|
||||
"image": "gcr.io/google-containers/nginx:latest",
|
||||
"name": "hello3"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
|
||||
// out
|
||||
t.Logf("Running test %d...", i+1)
|
||||
out, err := strategicMergePatch(log.Log, string(test.rawResource), string(test.rawPolicy))
|
||||
assert.NilError(t, err)
|
||||
|
||||
// expect
|
||||
var expectUnstr unstructured.Unstructured
|
||||
err = json.Unmarshal(test.expected, &expectUnstr)
|
||||
assert.NilError(t, err)
|
||||
|
||||
expectString, err := json.Marshal(expectUnstr.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assertnew.Equal(t, string(expectString), string(out), fmt.Sprintf("test %v fails", i))
|
||||
// has assertions inside
|
||||
areEqualJSONs(t, test.expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,25 @@ type ConditionError struct {
|
|||
}
|
||||
|
||||
func (ce ConditionError) Error() string {
|
||||
return fmt.Sprintf("Condition failed: %s", ce.errorChain.Error())
|
||||
return fmt.Sprintf("condition failed: %s", ce.errorChain.Error())
|
||||
}
|
||||
|
||||
func NewConditionError(err error) error {
|
||||
return ConditionError{err}
|
||||
}
|
||||
|
||||
type GlobalConditionError struct {
|
||||
errorChain error
|
||||
}
|
||||
|
||||
func (ce GlobalConditionError) Error() string {
|
||||
return fmt.Sprintf("global condition failed: %s", ce.errorChain.Error())
|
||||
}
|
||||
|
||||
func NewGlobalConditionError(err error) error {
|
||||
return GlobalConditionError{err}
|
||||
}
|
||||
|
||||
// preProcessPattern - Dynamically preProcess the yaml
|
||||
// 1> For conditional anchor remove anchors from the pattern.
|
||||
// 2> For Adding anchors remove anchor tags.
|
||||
|
@ -52,7 +64,6 @@ func preProcessRecursive(logger logr.Logger, pattern, resource *yaml.RNode) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
// walkMap - walk through the MappingNode
|
||||
func walkMap(logger logr.Logger, pattern, resource *yaml.RNode) error {
|
||||
var err error
|
||||
|
||||
|
@ -66,24 +77,23 @@ func walkMap(logger logr.Logger, pattern, resource *yaml.RNode) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fields, err := pattern.Fields()
|
||||
nonAnchors, err := filterKeys(pattern, func(key string) bool {
|
||||
return !hasAnchor(key)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
var resourceNode *yaml.RNode
|
||||
var resourceValue *yaml.RNode
|
||||
|
||||
for _, field := range nonAnchors {
|
||||
if resource == nil || resource.Field(field) == nil {
|
||||
// In case if we have pattern, but not corresponding resource part,
|
||||
// just walk down and remove all anchors. nil here indicates that
|
||||
// resourceNode is empty
|
||||
resourceNode = nil
|
||||
resourceValue = nil
|
||||
} else {
|
||||
resourceNode = resource.Field(field).Value
|
||||
resourceValue = resource.Field(field).Value
|
||||
}
|
||||
|
||||
err := preProcessRecursive(logger, pattern.Field(field).Value, resourceNode)
|
||||
err := preProcessRecursive(logger, pattern.Field(field).Value, resourceValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -92,7 +102,6 @@ func walkMap(logger logr.Logger, pattern, resource *yaml.RNode) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// walkList - walk through array elements
|
||||
func walkList(logger logr.Logger, pattern, resource *yaml.RNode) error {
|
||||
elements, err := pattern.Elements()
|
||||
if err != nil {
|
||||
|
@ -127,17 +136,32 @@ func processListOfMaps(logger logr.Logger, pattern, resource *yaml.RNode) error
|
|||
|
||||
for _, patternElement := range patternElements {
|
||||
// If pattern has conditions, look for matching elements and process them
|
||||
if hasAnchors(patternElement) {
|
||||
hasAnyAnchor := hasAnchors(patternElement, hasAnchor)
|
||||
hasGlobalConditions := hasAnchors(patternElement, anchor.IsGlobalAnchor)
|
||||
if hasAnyAnchor {
|
||||
|
||||
anyGlobalConditionPassed := false
|
||||
var lastGlobalAnchorError error = nil
|
||||
|
||||
for _, resourceElement := range resourceElements {
|
||||
err := preProcessRecursive(logger, patternElement, resourceElement)
|
||||
if err != nil {
|
||||
if _, ok := err.(ConditionError); ok {
|
||||
switch err.(type) {
|
||||
case ConditionError:
|
||||
// Skip element, if condition has failed
|
||||
continue
|
||||
case GlobalConditionError:
|
||||
lastGlobalAnchorError = err
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
} else {
|
||||
if hasGlobalConditions {
|
||||
// global anchor has passed, there is no need to return an error
|
||||
anyGlobalConditionPassed = true
|
||||
}
|
||||
|
||||
// If condition is satisfied, create new pattern list element based on patternElement
|
||||
// but related with current resource element by name.
|
||||
// Resource element must have name. Without name kustomize won't be able to update this element.
|
||||
|
@ -148,11 +172,16 @@ func processListOfMaps(logger logr.Logger, pattern, resource *yaml.RNode) error
|
|||
}
|
||||
|
||||
newNode := patternElement.Copy()
|
||||
err := deleteConditionsFromNestedMaps(newNode)
|
||||
empty, err := deleteConditionsFromNestedMaps(newNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Do not add an empty element to the patch
|
||||
if empty {
|
||||
continue
|
||||
}
|
||||
|
||||
err = newNode.PipeE(yaml.SetField("name", resourceElementName.Value))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -164,6 +193,10 @@ func processListOfMaps(logger logr.Logger, pattern, resource *yaml.RNode) error
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !anyGlobalConditionPassed && lastGlobalAnchorError != nil {
|
||||
return lastGlobalAnchorError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,23 +206,18 @@ func processListOfMaps(logger logr.Logger, pattern, resource *yaml.RNode) error
|
|||
// validateConditions checks all conditions from current map.
|
||||
// If at least one condition fails, return error.
|
||||
// If caller handles list of maps and gets an error, it must skip element.
|
||||
// If caller handles list of maps and gets GlobalConditionError, it must skip entire rule.
|
||||
// If caller handles map, it must stop processing and skip entire rule.
|
||||
func validateConditions(logger logr.Logger, pattern, resource *yaml.RNode) error {
|
||||
conditions, err := filterKeys(pattern, anchor.IsConditionAnchor)
|
||||
var err error
|
||||
err = validateConditionsInternal(logger, pattern, resource, anchor.IsGlobalAnchor)
|
||||
if err != nil {
|
||||
return err
|
||||
return NewGlobalConditionError(err)
|
||||
}
|
||||
|
||||
for _, condition := range conditions {
|
||||
conditionKey := removeAnchor(condition)
|
||||
if resource == nil || resource.Field(conditionKey) == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
err = checkCondition(logger, pattern.Field(condition).Value, resource.Field(conditionKey).Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = validateConditionsInternal(logger, pattern, resource, anchor.IsConditionAnchor)
|
||||
if err != nil {
|
||||
return NewConditionError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -239,7 +267,11 @@ func filterKeys(pattern *yaml.RNode, condition func(string) bool) ([]string, err
|
|||
return keys, nil
|
||||
}
|
||||
|
||||
func hasAnchors(pattern *yaml.RNode) bool {
|
||||
func hasAnchor(key string) bool {
|
||||
return anchor.ContainsCondition(key) || anchor.IsAddingAnchor(key)
|
||||
}
|
||||
|
||||
func hasAnchors(pattern *yaml.RNode, isAnchor func(key string) bool) bool {
|
||||
if yaml.MappingNode == pattern.YNode().Kind {
|
||||
fields, err := pattern.Fields()
|
||||
if err != nil {
|
||||
|
@ -247,13 +279,13 @@ func hasAnchors(pattern *yaml.RNode) bool {
|
|||
}
|
||||
|
||||
for _, key := range fields {
|
||||
if anchor.IsConditionAnchor(key) || anchor.IsAddingAnchor(key) {
|
||||
if isAnchor(key) {
|
||||
return true
|
||||
}
|
||||
|
||||
patternNode := pattern.Field(key)
|
||||
if !patternNode.IsNilOrEmpty() {
|
||||
if hasAnchors(patternNode.Value) {
|
||||
if hasAnchors(patternNode.Value, isAnchor) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -304,41 +336,54 @@ func checkCondition(logger logr.Logger, pattern *yaml.RNode, resource *yaml.RNod
|
|||
}
|
||||
|
||||
_, err = validate.ValidateResourceWithPattern(logger, resourceInterface, patternInterface)
|
||||
if err != nil {
|
||||
return NewConditionError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func deleteConditionsFromNestedMaps(pattern *yaml.RNode) error {
|
||||
func deleteConditionsFromNestedMaps(pattern *yaml.RNode) (bool, error) {
|
||||
if pattern.YNode().Kind != yaml.MappingNode {
|
||||
return nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fields, err := pattern.Fields()
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
if anchor.IsConditionAnchor(field) {
|
||||
if anchor.ContainsCondition(field) {
|
||||
err = pattern.PipeE(yaml.Clear(field))
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
} else {
|
||||
child := pattern.Field(field).Value
|
||||
if child != nil {
|
||||
err = deleteConditionsFromNestedMaps(child)
|
||||
empty, err := deleteConditionsFromNestedMaps(child)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
if empty {
|
||||
err = pattern.PipeE(yaml.Clear(field))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
fields, err = pattern.Fields()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if len(fields) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func deleteConditionElements(pattern *yaml.RNode) error {
|
||||
|
@ -381,7 +426,7 @@ func deleteAnchors(node *yaml.RNode) (bool, error) {
|
|||
}
|
||||
|
||||
func deleteAnchorsInMap(node *yaml.RNode) (bool, error) {
|
||||
conditions, err := filterKeys(node, anchor.IsConditionAnchor)
|
||||
conditions, err := filterKeys(node, anchor.ContainsCondition)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -399,22 +444,28 @@ func deleteAnchorsInMap(node *yaml.RNode) (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
|
||||
needToDelete := true
|
||||
|
||||
// Go further through the map elements.
|
||||
hasOnlyAnchors := true
|
||||
for _, field := range fields {
|
||||
ok, err := deleteAnchors(node.Field(field).Value)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// If we have at least one element without annchor,
|
||||
// then we don't need to delete this element.
|
||||
if !ok {
|
||||
hasOnlyAnchors = false
|
||||
if ok {
|
||||
err = node.PipeE(yaml.Clear(field))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
} else {
|
||||
// If we have at least one element without anchor,
|
||||
// then we don't need to delete this element.
|
||||
needToDelete = false
|
||||
}
|
||||
}
|
||||
|
||||
return hasOnlyAnchors, nil
|
||||
return needToDelete, nil
|
||||
}
|
||||
|
||||
func deleteAnchorsInList(node *yaml.RNode) (bool, error) {
|
||||
|
@ -423,8 +474,10 @@ func deleteAnchorsInList(node *yaml.RNode) (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
|
||||
wasEmpty := len(elements) == 0
|
||||
|
||||
for i, element := range elements {
|
||||
if hasAnchors(element) {
|
||||
if hasAnchors(element, hasAnchor) {
|
||||
deleteListElement(node, i)
|
||||
} else {
|
||||
// This element also could have some conditions
|
||||
|
@ -434,9 +487,6 @@ func deleteAnchorsInList(node *yaml.RNode) (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if ok {
|
||||
deleteListElement(node, i)
|
||||
}
|
||||
|
@ -447,7 +497,7 @@ func deleteAnchorsInList(node *yaml.RNode) (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(elements) == 0 {
|
||||
if len(elements) == 0 && !wasEmpty {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -458,3 +508,24 @@ func deleteListElement(list *yaml.RNode, i int) {
|
|||
content := list.YNode().Content
|
||||
list.YNode().Content = append(content[:i], content[i+1:]...)
|
||||
}
|
||||
|
||||
func validateConditionsInternal(logger logr.Logger, pattern, resource *yaml.RNode, filter func(string) bool) error {
|
||||
conditions, err := filterKeys(pattern, filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, condition := range conditions {
|
||||
conditionKey := removeAnchor(condition)
|
||||
if resource == nil || resource.Field(conditionKey) == nil {
|
||||
return fmt.Errorf("could not found \"%s\" key in the resource", conditionKey)
|
||||
}
|
||||
|
||||
err = checkCondition(logger, pattern.Field(condition).Value, resource.Field(conditionKey).Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -29,6 +29,59 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
rawResource []byte
|
||||
expectedPatch []byte
|
||||
}{
|
||||
{
|
||||
rawPolicy: []byte(`{
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": "true"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"<(emptyDir)": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
rawResource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "static-web",
|
||||
"labels": {
|
||||
"role": "myrole"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "web",
|
||||
"image": "1nginx"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"emptyDir": {},
|
||||
"name": "cache-volume"
|
||||
},
|
||||
{
|
||||
"secret": {
|
||||
"secretName": "default-token-6gplg"
|
||||
},
|
||||
"name": "default-token-6gplg"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
expectedPatch: []byte(`{
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`{
|
||||
"metadata": null
|
||||
|
@ -177,11 +230,6 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
}`),
|
||||
expectedPatch: []byte(`{
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
|
@ -222,11 +270,6 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
}`),
|
||||
expectedPatch: []byte(`{
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
|
@ -276,14 +319,6 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
}`),
|
||||
expectedPatch: []byte(`{
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello"
|
||||
},
|
||||
{
|
||||
"name": "hello2"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
|
@ -351,13 +386,6 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
"labels": {
|
||||
"add-labels": "add"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"name": "cache-volume"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
},
|
||||
|
@ -412,15 +440,7 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
]
|
||||
}
|
||||
}`),
|
||||
expectedPatch: []byte(`{
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"name": "cache-volume"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
expectedPatch: []byte(`{}`),
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`{
|
||||
|
@ -606,8 +626,7 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
"metadata": {
|
||||
"annotations": {
|
||||
"annotation2": "atest2"
|
||||
},
|
||||
"labels": {}
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
|
@ -686,52 +705,56 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
{
|
||||
rawPolicy: []byte(`{
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"(key1)": "value1",
|
||||
}
|
||||
"annotations": {
|
||||
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": true
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
"volumes": [
|
||||
{
|
||||
"name": "busybox",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
"hostPath": {
|
||||
"<(path)": "*data"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
rawResource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "hello"
|
||||
"name": "nginx"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello",
|
||||
"image": "busybox"
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest",
|
||||
"imagePullPolicy": "Never",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/cache",
|
||||
"name": "cache-volume"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "cache-volume",
|
||||
"hostPath": {
|
||||
"path": "/data",
|
||||
"type": "Directory"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
expectedPatch: []byte(`{
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "busybox",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
}
|
||||
]
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"cluster-autoscaler.kubernetes.io/safe-to-evict": true
|
||||
}
|
||||
}
|
||||
}`),
|
||||
},
|
||||
|
@ -831,6 +854,7 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
|
||||
t.Logf("Running test %d...", i+1)
|
||||
preProcessedPolicy, err := preProcessStrategicMergePatch(log.Log, string(test.rawPolicy), string(test.rawResource))
|
||||
assert.NilError(t, err)
|
||||
|
@ -900,7 +924,7 @@ func Test_CheckConditionAnchor_DoesNotMatch(t *testing.T) {
|
|||
resource := yaml.MustParse(string(resourceRaw))
|
||||
|
||||
err := checkCondition(log.Log, pattern, resource)
|
||||
assert.Error(t, err, "Condition failed: Validation rule failed at '/key1/' to validate value 'sample' with pattern 'value*'")
|
||||
assert.Error(t, err, "Validation rule failed at '/key1/' to validate value 'sample' with pattern 'value*'")
|
||||
}
|
||||
|
||||
func Test_ValidateConditions_MapWithOneCondition_Matches(t *testing.T) {
|
||||
|
@ -1045,7 +1069,8 @@ func Test_ConditionCheck_SeveralElementsMatchExceptOne(t *testing.T) {
|
|||
patternRaw := []byte(`{
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "gcr.io/google-containers/busybox:*"
|
||||
"(name)": "hello?",
|
||||
"image": "gcr.io/google-containers/busybox:1"
|
||||
}
|
||||
]
|
||||
}`)
|
||||
|
@ -1073,8 +1098,57 @@ func Test_ConditionCheck_SeveralElementsMatchExceptOne(t *testing.T) {
|
|||
err := preProcessPattern(log.Log, pattern, containers)
|
||||
assert.NilError(t, err)
|
||||
|
||||
containersElements, err := pattern.Field("containers").Value.Elements()
|
||||
patternContainers := pattern.Field("containers")
|
||||
assert.Assert(t, patternContainers != nil)
|
||||
assert.Assert(t, patternContainers.Value != nil)
|
||||
|
||||
elements, err := patternContainers.Value.Elements()
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.Equal(t, len(containersElements), 2)
|
||||
assert.Equal(t, len(elements), 2)
|
||||
}
|
||||
|
||||
func Test_NonExistingKeyMustFailPreprocessing(t *testing.T) {
|
||||
rawPattern := []byte(`{
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"(key1)": "value1",
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "busybox",
|
||||
"image": "gcr.io/google-containers/busybox:latest"
|
||||
}
|
||||
],
|
||||
"imagePullSecrets": [
|
||||
{
|
||||
"name": "regcred"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
|
||||
rawResource := []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "hello"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "hello",
|
||||
"image": "busybox"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
|
||||
pattern := yaml.MustParse(string(rawPattern))
|
||||
resource := yaml.MustParse(string(rawResource))
|
||||
|
||||
err := preProcessPattern(log.Log, pattern, resource)
|
||||
assert.Error(t, err, "condition failed: could not found \"key1\" key in the resource")
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ func removeAnchor(key string) string {
|
|||
return key[1 : len(key)-1]
|
||||
}
|
||||
|
||||
if commonAnchors.IsExistenceAnchor(key) || commonAnchors.IsAddingAnchor(key) || commonAnchors.IsEqualityAnchor(key) || commonAnchors.IsNegationAnchor(key) {
|
||||
if commonAnchors.IsExistenceAnchor(key) || commonAnchors.IsAddingAnchor(key) || commonAnchors.IsEqualityAnchor(key) || commonAnchors.IsNegationAnchor(key) || commonAnchors.IsGlobalAnchor(key) {
|
||||
return key[2 : len(key)-1]
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/kyverno/kyverno/pkg/engine/anchor"
|
||||
commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor/common"
|
||||
"github.com/kyverno/kyverno/pkg/engine/common"
|
||||
"github.com/kyverno/kyverno/pkg/engine/operator"
|
||||
"github.com/kyverno/kyverno/pkg/engine/wildcards"
|
||||
|
@ -20,7 +19,8 @@ func ValidateResourceWithPattern(logger logr.Logger, resource, pattern interface
|
|||
ac := common.NewAnchorMap()
|
||||
elemPath, err := validateResourceElement(logger, resource, pattern, pattern, "/", ac)
|
||||
if err != nil {
|
||||
if common.IsConditionalAnchorError(err.Error()) {
|
||||
if common.IsConditionalAnchorError(err.Error()) || common.IsGlobalAnchorError(err.Error()) {
|
||||
logger.V(3).Info(ac.AnchorError.Message)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
|
@ -102,12 +102,7 @@ func validateMap(log logr.Logger, resourceMap, patternMap map[string]interface{}
|
|||
// if there are resource values at same level, then anchor acts as conditional instead of a strict check
|
||||
// but if there are non then its a if then check
|
||||
if err != nil {
|
||||
// If Conditional anchor fails then we don't process the resources
|
||||
if commonAnchors.IsConditionAnchor(key) {
|
||||
ac.AnchorError = common.NewConditionalAnchorError(fmt.Sprintf("condition anchor did not satisfy: %s", err.Error()))
|
||||
log.V(3).Info(ac.AnchorError.Message)
|
||||
return "", ac.AnchorError.Error()
|
||||
}
|
||||
// If global anchor fails then we don't process the resource
|
||||
return handlerPath, err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1394,6 +1394,11 @@ func TestConditionalAnchorWithMultiplePatterns(t *testing.T) {
|
|||
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
|
||||
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"}]}}`),
|
||||
nilErr: false,
|
||||
}, {
|
||||
name: "check global anchor",
|
||||
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
|
||||
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"}]}}`),
|
||||
nilErr: true,
|
||||
},
|
||||
{
|
||||
name: "test-4",
|
||||
|
|
|
@ -31,7 +31,7 @@ func (v *Validate) Validate() (string, error) {
|
|||
}
|
||||
|
||||
if rule.Pattern != nil {
|
||||
if path, err := common.ValidatePattern(rule.Pattern, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor}); err != nil {
|
||||
if path, err := common.ValidatePattern(rule.Pattern, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor, commonAnchors.IsGlobalAnchor}); err != nil {
|
||||
return fmt.Sprintf("pattern.%s", path), err
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func (v *Validate) Validate() (string, error) {
|
|||
return "anyPattern", fmt.Errorf("failed to deserialize anyPattern, expect array: %v", err)
|
||||
}
|
||||
for i, pattern := range anyPattern {
|
||||
if path, err := common.ValidatePattern(pattern, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor}); err != nil {
|
||||
if path, err := common.ValidatePattern(pattern, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor, commonAnchors.IsGlobalAnchor}); err != nil {
|
||||
return fmt.Sprintf("anyPattern[%d].%s", i, path), err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ spec:
|
|||
+(cluster-autoscaler.kubernetes.io/safe-to-evict): "true"
|
||||
spec:
|
||||
volumes:
|
||||
- (emptyDir): {}
|
||||
- <(emptyDir): {}
|
||||
- name: annotate-host-path
|
||||
match:
|
||||
resources:
|
||||
|
@ -34,5 +34,5 @@ spec:
|
|||
+(cluster-autoscaler.kubernetes.io/safe-to-evict): "true"
|
||||
spec:
|
||||
volumes:
|
||||
- (hostPath):
|
||||
path: "*"
|
||||
- hostPath:
|
||||
<(path): "*"
|
||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
kind: Pod
|
||||
metadata:
|
||||
name: pod-with-default-volume
|
||||
creationTimestamp: "2020-09-21T12:56:35Z"
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/test-webserver
|
||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
kind: Pod
|
||||
metadata:
|
||||
name: pod-with-default-volume
|
||||
creationTimestamp: "2020-09-21T12:56:35Z"
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/test-webserver
|
||||
|
|
|
@ -4,7 +4,7 @@ input:
|
|||
resource: test/resources/pod-with-default-volume.yaml
|
||||
expected:
|
||||
mutation:
|
||||
patchedresource: test/resources/pod-with-default-volume.yaml
|
||||
patchedresource: test/output/pod-with-default-volume.yaml
|
||||
policyresponse:
|
||||
policy:
|
||||
namespace: ''
|
||||
|
|
Loading…
Add table
Reference in a new issue