mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
ignore non-policy files in CLI and improve validation messages (#1362)
* improve validation message * improve error behaviors * fix tests * fix tests
This commit is contained in:
parent
a64915128b
commit
6afd2e6f3a
20 changed files with 249 additions and 205 deletions
1
go.mod
1
go.mod
|
@ -25,6 +25,7 @@ require (
|
|||
github.com/minio/minio v0.0.0-20200114012931-30922148fbb5
|
||||
github.com/onsi/ginkgo v1.11.0
|
||||
github.com/onsi/gomega v1.8.1
|
||||
github.com/ory/go-acc v0.2.6 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||
github.com/spf13/cobra v1.0.0
|
||||
|
|
27
go.sum
27
go.sum
|
@ -109,8 +109,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/siphash v1.1.0 h1:1Rs9eTUlZLPBEvV+2sTaM8O0NWn0ppbgqS7p11aWawI=
|
||||
github.com/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
||||
github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE=
|
||||
github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po=
|
||||
github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
|
@ -428,6 +432,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn
|
|||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
|
@ -484,6 +490,8 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
|
|||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
|
@ -530,12 +538,18 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
|||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/ory/go-acc v0.2.6 h1:YfI+L9dxI7QCtWn2RbawqO0vXhiThdXu/RgizJBbaq0=
|
||||
github.com/ory/go-acc v0.2.6/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw=
|
||||
github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE=
|
||||
github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
|
||||
github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
|
||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
|
@ -608,6 +622,7 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
|||
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
|
||||
|
@ -616,11 +631,15 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
|
|||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
|
@ -641,6 +660,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 h1:hNna6Fi0eP1f2sMBe/rJicDmaHmoXGe1Ta84FPYHLuE=
|
||||
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0=
|
||||
github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
|
@ -712,6 +733,7 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
|
|||
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -792,6 +814,8 @@ golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -880,6 +904,9 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
|||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
|
|
|
@ -160,7 +160,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
|||
Context: ctx,
|
||||
NewResource: *resourceUnstructured}
|
||||
er := Mutate(policyContext)
|
||||
expectedErrorStr := "variable request.object.metadata.name1 not found (path: /spec/name)"
|
||||
expectedErrorStr := "variable request.object.metadata.name1 not resolved at path /spec/name"
|
||||
t.Log(er.PolicyResponse.Rules[0].Message)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, expectedErrorStr)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package engine
|
|||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
@ -246,8 +247,8 @@ func isSameRules(oldRules []response.RuleResponse, newRules []response.RuleRespo
|
|||
// validatePatterns validate pattern and anyPattern
|
||||
func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstructured.Unstructured, rule kyverno.Rule) (resp response.RuleResponse) {
|
||||
startTime := time.Now()
|
||||
logger := log.WithValues("rule", rule.Name)
|
||||
logger.V(4).Info("start processing rule", "startTime", startTime)
|
||||
logger := log.WithValues("rule", rule.Name, "name", resource.GetName(), "kind", resource.GetKind())
|
||||
logger.V(5).Info("start processing rule", "startTime", startTime)
|
||||
resp.Name = rule.Name
|
||||
resp.Type = utils.Validation.String()
|
||||
defer func() {
|
||||
|
@ -255,34 +256,26 @@ func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstr
|
|||
logger.V(4).Info("finished processing rule", "processingTime", resp.RuleStats.ProcessingTime.String())
|
||||
}()
|
||||
|
||||
// work on a copy of validation rule
|
||||
validationRule := rule.Validation.DeepCopy()
|
||||
|
||||
// either pattern or anyPattern can be specified in Validation rule
|
||||
if validationRule.Pattern != nil {
|
||||
// substitute variables in the pattern
|
||||
pattern := validationRule.Pattern
|
||||
var err error
|
||||
if pattern, err = variables.SubstituteVars(logger, ctx, pattern); err != nil {
|
||||
// variable substitution failed
|
||||
resp.Success = false
|
||||
resp.Message = fmt.Sprintf("Validation error: %s; Validation rule '%s' failed. '%s'",
|
||||
rule.Validation.Message, rule.Name, err)
|
||||
resp.Message = fmt.Sprintf("variable substitution failed for rule %s: %s", rule.Name, err.Error())
|
||||
return resp
|
||||
}
|
||||
|
||||
if path, err := validate.ValidateResourceWithPattern(logger, resource.Object, pattern); err != nil {
|
||||
// validation failed
|
||||
logger.V(5).Info(err.Error())
|
||||
logger.V(3).Info("validation failed", "path", path, "error", err.Error())
|
||||
resp.Success = false
|
||||
resp.Message = fmt.Sprintf("Validation error: %s; Validation rule %s failed at path %s",
|
||||
rule.Validation.Message, rule.Name, path)
|
||||
resp.Message = buildErrorMessage(rule, path)
|
||||
return resp
|
||||
}
|
||||
|
||||
logger.V(4).Info("successfully processed rule")
|
||||
resp.Success = true
|
||||
resp.Message = fmt.Sprintf("Validation rule '%s' succeeded.", rule.Name)
|
||||
resp.Message = fmt.Sprintf("validation rule '%s' passed.", rule.Name)
|
||||
return resp
|
||||
}
|
||||
|
||||
|
@ -294,31 +287,32 @@ func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstr
|
|||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
resp.Success = false
|
||||
resp.Message = fmt.Sprintf("Failed to deserialize anyPattern, expect type array: %v", err)
|
||||
resp.Message = fmt.Sprintf("failed to deserialize anyPattern, expected type array: %v", err)
|
||||
return resp
|
||||
}
|
||||
|
||||
for idx, pattern := range anyPatterns {
|
||||
if pattern, err = variables.SubstituteVars(logger, ctx, pattern); err != nil {
|
||||
// variable substitution failed
|
||||
failedSubstitutionsErrors = append(failedSubstitutionsErrors, err)
|
||||
continue
|
||||
}
|
||||
_, err := validate.ValidateResourceWithPattern(logger, resource.Object, pattern)
|
||||
|
||||
path, err := validate.ValidateResourceWithPattern(logger, resource.Object, pattern)
|
||||
if err == nil {
|
||||
resp.Success = true
|
||||
resp.Message = fmt.Sprintf("Validation rule '%s' anyPattern[%d] succeeded.", rule.Name, idx)
|
||||
resp.Message = fmt.Sprintf("validation rule '%s' anyPattern[%d] passed.", rule.Name, idx)
|
||||
return resp
|
||||
}
|
||||
logger.V(4).Info(fmt.Sprintf("validation rule failed for anyPattern[%d]", idx), "message", rule.Validation.Message)
|
||||
patternErr := fmt.Errorf("anyPattern[%d] failed; %s", idx, err)
|
||||
|
||||
logger.V(4).Info("validation rule failed", "anyPattern[%d]", idx, "path", path)
|
||||
patternErr := fmt.Errorf("Rule %s[%d] failed at path %s.", rule.Name, idx, path)
|
||||
failedAnyPatternsErrors = append(failedAnyPatternsErrors, patternErr)
|
||||
}
|
||||
|
||||
// Substitution failures
|
||||
if len(failedSubstitutionsErrors) > 0 {
|
||||
resp.Success = false
|
||||
resp.Message = fmt.Sprintf("Substitutions failed: %v", failedSubstitutionsErrors)
|
||||
resp.Message = fmt.Sprintf("failed to substitute variables: %v", failedSubstitutionsErrors)
|
||||
return resp
|
||||
}
|
||||
|
||||
|
@ -328,15 +322,38 @@ func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstr
|
|||
for _, err := range failedAnyPatternsErrors {
|
||||
errorStr = append(errorStr, err.Error())
|
||||
}
|
||||
resp.Success = false
|
||||
|
||||
log.V(4).Info(fmt.Sprintf("Validation rule '%s' failed. %s", rule.Name, errorStr))
|
||||
if rule.Validation.Message == "" {
|
||||
resp.Message = fmt.Sprintf("Validation rule '%s' has failed", rule.Name)
|
||||
} else {
|
||||
resp.Message = rule.Validation.Message
|
||||
}
|
||||
|
||||
resp.Success = false
|
||||
resp.Message = buildAnyPatternErrorMessage(rule, errorStr)
|
||||
return resp
|
||||
}
|
||||
}
|
||||
return response.RuleResponse{}
|
||||
}
|
||||
|
||||
func buildErrorMessage(rule kyverno.Rule, path string) string {
|
||||
if rule.Validation.Message == "" {
|
||||
return fmt.Sprintf("validation error: rule %s failed at path %s", rule.Name, path)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(rule.Validation.Message, ".") {
|
||||
return fmt.Sprintf("validation error: %s Rule %s failed at path %s", rule.Validation.Message, rule.Name, path)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("validation error: %s. Rule %s failed at path %s", rule.Validation.Message, rule.Name, path)
|
||||
}
|
||||
|
||||
func buildAnyPatternErrorMessage(rule kyverno.Rule, errors []string) string {
|
||||
errStr := strings.Join(errors, " ")
|
||||
if rule.Validation.Message == "" {
|
||||
return fmt.Sprintf("validation error: %s", errStr)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(rule.Validation.Message, ".") {
|
||||
return fmt.Sprintf("validation error: %s %s", rule.Validation.Message, errStr)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("validation error: %s. %s", rule.Validation.Message, errStr)
|
||||
}
|
||||
|
|
|
@ -124,8 +124,8 @@ func TestValidate_image_tag_fail(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
msgs := []string{
|
||||
"Validation rule 'validate-tag' succeeded.",
|
||||
"Validation error: imagePullPolicy 'Always' required with tag 'latest'; Validation rule validate-latest failed at path /spec/containers/0/imagePullPolicy/",
|
||||
"validation rule 'validate-tag' passed.",
|
||||
"validation error: imagePullPolicy 'Always' required with tag 'latest'. Rule validate-latest failed at path /spec/containers/0/imagePullPolicy/",
|
||||
}
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -223,8 +223,8 @@ func TestValidate_image_tag_pass(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
msgs := []string{
|
||||
"Validation rule 'validate-tag' succeeded.",
|
||||
"Validation rule 'validate-latest' succeeded.",
|
||||
"validation rule 'validate-tag' passed.",
|
||||
"validation rule 'validate-latest' passed.",
|
||||
}
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -301,7 +301,7 @@ func TestValidate_Fail_anyPattern(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"A namespace is required"}
|
||||
msgs := []string{"validation error: A namespace is required. Rule check-default-namespace[0] failed at path /metadata/namespace/. Rule check-default-namespace[1] failed at path /metadata/namespace/."}
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ func TestValidate_host_network_port(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation error: Host network and port are not allowed; Validation rule validate-host-network-port failed at path /spec/containers/0/ports/0/hostPort/"}
|
||||
msgs := []string{"validation error: Host network and port are not allowed. Rule validate-host-network-port failed at path /spec/containers/0/ports/0/hostPort/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -473,7 +473,7 @@ func TestValidate_anchor_arraymap_pass(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation rule 'validate-host-path' succeeded."}
|
||||
msgs := []string{"validation rule 'validate-host-path' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -561,7 +561,7 @@ func TestValidate_anchor_arraymap_fail(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation error: Host path '/var/lib/' is not allowed; Validation rule validate-host-path failed at path /spec/volumes/0/hostPath/path/"}
|
||||
msgs := []string{"validation error: Host path '/var/lib/' is not allowed. Rule validate-host-path failed at path /spec/volumes/0/hostPath/path/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -631,7 +631,7 @@ func TestValidate_anchor_map_notfound(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation rule 'pod rule 2' succeeded."}
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -704,7 +704,7 @@ func TestValidate_anchor_map_found_valid(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation rule 'pod rule 2' succeeded."}
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -777,7 +777,7 @@ func TestValidate_anchor_map_found_invalid(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation error: pod: validate run as non root user; Validation rule pod rule 2 failed at path /spec/securityContext/runAsNonRoot/"}
|
||||
msgs := []string{"validation error: pod: validate run as non root user. Rule pod rule 2 failed at path /spec/securityContext/runAsNonRoot/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -852,7 +852,7 @@ func TestValidate_AnchorList_pass(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation rule 'pod image rule' succeeded."}
|
||||
msgs := []string{"validation rule 'pod image rule' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
t.Log(r.Message)
|
||||
|
@ -927,11 +927,6 @@ func TestValidate_AnchorList_fail(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
// msgs := []string{"Validation rule 'pod image rule' failed at '/spec/containers/1/name/' for resource Pod//myapp-pod."}
|
||||
// for index, r := range er.PolicyResponse.Rules {
|
||||
// // t.Log(r.Message)
|
||||
// assert.Equal(t, r.Message, msgs[index])
|
||||
// }
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -1002,12 +997,6 @@ func TestValidate_existenceAnchor_fail(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
// msgs := []string{"Validation rule 'pod image rule' failed at '/spec/containers/' for resource Pod//myapp-pod."}
|
||||
|
||||
// for index, r := range er.PolicyResponse.Rules {
|
||||
// t.Log(r.Message)
|
||||
// assert.Equal(t, r.Message, msgs[index])
|
||||
// }
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1067,7 @@ func TestValidate_existenceAnchor_pass(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation rule 'pod image rule' succeeded."}
|
||||
msgs := []string{"validation rule 'pod image rule' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -1166,7 +1155,7 @@ func TestValidate_negationAnchor_deny(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation error: Host path is not allowed; Validation rule validate-host-path failed at path /spec/volumes/0/hostPath/"}
|
||||
msgs := []string{"validation error: Host path is not allowed. Rule validate-host-path failed at path /spec/volumes/0/hostPath/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -1253,7 +1242,7 @@ func TestValidate_negationAnchor_pass(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := Validate(PolicyContext{Policy: policy, NewResource: *resourceUnstructured})
|
||||
msgs := []string{"Validation rule 'validate-host-path' succeeded."}
|
||||
msgs := []string{"validation rule 'validate-host-path' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
|
@ -1330,7 +1319,8 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
|
|||
NewResource: *resourceUnstructured}
|
||||
er := Validate(policyContext)
|
||||
assert.Assert(t, !er.PolicyResponse.Rules[0].Success)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "Validation error: ; Validation rule 'test-path-not-exist' failed. 'variable request.object.metadata.name1 not found (path: /spec/containers/0/name)'")
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message,
|
||||
"variable substitution failed for rule test-path-not-exist: variable request.object.metadata.name1 not resolved at path /spec/containers/0/name")
|
||||
}
|
||||
|
||||
func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfies(t *testing.T) {
|
||||
|
@ -1421,7 +1411,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfies(t *t
|
|||
NewResource: *resourceUnstructured}
|
||||
er := Validate(policyContext)
|
||||
assert.Assert(t, er.PolicyResponse.Rules[0].Success)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "Validation rule 'test-path-not-exist' anyPattern[1] succeeded.")
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "validation rule 'test-path-not-exist' anyPattern[1] passed.")
|
||||
}
|
||||
|
||||
func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *testing.T) {
|
||||
|
@ -1512,7 +1502,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
|
|||
NewResource: *resourceUnstructured}
|
||||
er := Validate(policyContext)
|
||||
assert.Assert(t, !er.PolicyResponse.Rules[0].Success)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "Substitutions failed: [variable request.object.metadata.name1 not found (path: /spec/template/spec/containers/0/name) variable request.object.metadata.name2 not found (path: /spec/template/spec/containers/0/name)]")
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "failed to substitute variables: [variable request.object.metadata.name1 not resolved at path /spec/template/spec/containers/0/name variable request.object.metadata.name2 not resolved at path /spec/template/spec/containers/0/name]")
|
||||
}
|
||||
|
||||
func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatternSatisfy(t *testing.T) {
|
||||
|
@ -1603,9 +1593,9 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
|
|||
NewResource: *resourceUnstructured}
|
||||
er := Validate(policyContext)
|
||||
|
||||
// expectedMsg := "Validation error: ; Validation rule test-path-not-exist anyPattern[0] failed at path /spec/template/spec/containers/0/name/. Validation rule test-path-not-exist anyPattern[1] failed at path /spec/template/spec/containers/0/name/."
|
||||
assert.Assert(t, !er.PolicyResponse.Rules[0].Success)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "Validation rule 'test-path-not-exist' has failed")
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message,
|
||||
"validation error: Rule test-path-not-exist[0] failed at path /spec/template/spec/containers/0/name/. Rule test-path-not-exist[1] failed at path /spec/template/spec/containers/0/name/.")
|
||||
}
|
||||
|
||||
func Test_denyFeatureIssue744(t *testing.T) {
|
||||
|
|
|
@ -82,7 +82,7 @@ type NotFoundVariableErr struct {
|
|||
}
|
||||
|
||||
func (n NotFoundVariableErr) Error() string {
|
||||
return fmt.Sprintf("variable %v not found (path: %v)", n.variable, n.path)
|
||||
return fmt.Sprintf("variable %s not resolved at path %s", n.variable, n.path)
|
||||
}
|
||||
|
||||
// subValR resolves the variables if defined
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/response"
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/common"
|
||||
sanitizedError "github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
policy2 "github.com/kyverno/kyverno/pkg/policy"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
|
@ -59,18 +59,7 @@ type SkippedPolicy struct {
|
|||
Variable string `json:"variable"`
|
||||
}
|
||||
|
||||
func Command() *cobra.Command {
|
||||
var cmd *cobra.Command
|
||||
var resourcePaths []string
|
||||
var cluster, policyReport bool
|
||||
var mutateLogPath, variablesString, valuesFile, namespace string
|
||||
|
||||
kubernetesConfig := genericclioptions.NewConfigFlags(true)
|
||||
|
||||
cmd = &cobra.Command{
|
||||
Use: "apply",
|
||||
Short: "applies policies on resources",
|
||||
Example: fmt.Sprintf(`
|
||||
var applyHelp = `
|
||||
To apply on a resource:
|
||||
kyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2
|
||||
|
||||
|
@ -112,12 +101,25 @@ To apply policy with variables:
|
|||
<variable1 in policy2>: <value>
|
||||
<variable2 in policy2>: <value>
|
||||
|
||||
More info: https://kyverno.io/docs/kyverno-cli/
|
||||
`),
|
||||
More info: https://kyverno.io/docs/kyverno-cli/
|
||||
`
|
||||
|
||||
func Command() *cobra.Command {
|
||||
var cmd *cobra.Command
|
||||
var resourcePaths []string
|
||||
var cluster, policyReport bool
|
||||
var mutateLogPath, variablesString, valuesFile, namespace string
|
||||
|
||||
kubernetesConfig := genericclioptions.NewConfigFlags(true)
|
||||
|
||||
cmd = &cobra.Command{
|
||||
Use: "apply",
|
||||
Short: "applies policies on resources",
|
||||
Example: applyHelp,
|
||||
RunE: func(cmd *cobra.Command, policyPaths []string) (err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
log.Log.Error(err, "failed to sanitize")
|
||||
err = fmt.Errorf("internal error")
|
||||
}
|
||||
|
@ -125,20 +127,20 @@ To apply policy with variables:
|
|||
}()
|
||||
|
||||
if valuesFile != "" && variablesString != "" {
|
||||
return sanitizedError.NewWithError("pass the values either using set flag or values_file flag", err)
|
||||
return sanitizederror.NewWithError("pass the values either using set flag or values_file flag", err)
|
||||
}
|
||||
|
||||
variables, valuesMap, err := getVariable(variablesString, valuesFile)
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
return sanitizedError.NewWithError("failed to decode yaml", err)
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return sanitizederror.NewWithError("failed to decode yaml", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
openAPIController, err := openapi.NewOpenAPIController()
|
||||
if err != nil {
|
||||
return sanitizedError.NewWithError("failed to initialize openAPIController", err)
|
||||
return sanitizederror.NewWithError("failed to initialize openAPIController", err)
|
||||
}
|
||||
|
||||
var dClient *client.Client
|
||||
|
@ -154,33 +156,41 @@ To apply policy with variables:
|
|||
}
|
||||
|
||||
if len(policyPaths) == 0 {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("require policy"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("require policy"), err)
|
||||
}
|
||||
|
||||
policies, err := common.ValidateAndGetPolicies(policyPaths)
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
return sanitizedError.NewWithError("failed to mutate policies.", err)
|
||||
policies, errors := common.GetPolicies(policyPaths)
|
||||
if len(policies) == 0 {
|
||||
if len(errors) > 0 {
|
||||
return sanitizederror.NewWithErrors("failed to read policies", errors)
|
||||
}
|
||||
|
||||
return sanitizederror.New(fmt.Sprintf("no policies found in paths %v", policyPaths))
|
||||
}
|
||||
|
||||
if len(errors) > 0 && log.Log.V(1).Enabled() {
|
||||
fmt.Printf("ignoring errors: \n")
|
||||
for _, e := range errors {
|
||||
fmt.Printf(" %v \n", e.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if len(resourcePaths) == 0 && !cluster {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("resource file(s) or cluster required"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("resource file(s) or cluster required"), err)
|
||||
}
|
||||
|
||||
mutateLogPathIsDir, err := checkMutateLogPath(mutateLogPath)
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
return sanitizedError.NewWithError("failed to create file/folder", err)
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return sanitizederror.NewWithError("failed to create file/folder", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
mutatedPolicies, err := mutatePolices(policies)
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
return sanitizedError.NewWithError("failed to mutate policy", err)
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return sanitizederror.NewWithError("failed to mutate policy", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,12 +254,12 @@ To apply policy with variables:
|
|||
}
|
||||
|
||||
if len(common.PolicyHasVariables(*policy)) > 0 && len(thisPolicyResourceValues) == 0 {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("policy %s have variables. pass the values for the variables using set/values_file flag", policy.Name), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("policy %s have variables. pass the values for the variables using set/values_file flag", policy.Name), err)
|
||||
}
|
||||
|
||||
ers, validateErs, err := applyPolicyOnResource(policy, resource, mutateLogPath, mutateLogPathIsDir, thisPolicyResourceValues, rc, policyReport)
|
||||
if err != nil {
|
||||
return sanitizedError.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err)
|
||||
return sanitizederror.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err)
|
||||
}
|
||||
engineResponses = append(engineResponses, ers...)
|
||||
validateEngineResponses = append(validateEngineResponses, validateErs)
|
||||
|
@ -285,17 +295,17 @@ func getVariable(variablesString, valuesFile string) (variables map[string]strin
|
|||
if valuesFile != "" {
|
||||
yamlFile, err := ioutil.ReadFile(valuesFile)
|
||||
if err != nil {
|
||||
return variables, valuesMap, sanitizedError.NewWithError("unable to read yaml", err)
|
||||
return variables, valuesMap, sanitizederror.NewWithError("unable to read yaml", err)
|
||||
}
|
||||
|
||||
valuesBytes, err := yaml.ToJSON(yamlFile)
|
||||
if err != nil {
|
||||
return variables, valuesMap, sanitizedError.NewWithError("failed to convert json", err)
|
||||
return variables, valuesMap, sanitizederror.NewWithError("failed to convert json", err)
|
||||
}
|
||||
|
||||
values := &Values{}
|
||||
if err := json.Unmarshal(valuesBytes, values); err != nil {
|
||||
return variables, valuesMap, sanitizedError.NewWithError("failed to decode yaml", err)
|
||||
return variables, valuesMap, sanitizederror.NewWithError("failed to decode yaml", err)
|
||||
}
|
||||
|
||||
for _, p := range values.Policies {
|
||||
|
@ -323,8 +333,8 @@ func checkMutateLogPath(mutateLogPath string) (mutateLogPathIsDir bool, err erro
|
|||
|
||||
err := createFileOrFolder(mutateLogPath, mutateLogPathIsDir)
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
return mutateLogPathIsDir, sanitizedError.NewWithError("failed to create file/folder.", err)
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return mutateLogPathIsDir, sanitizederror.NewWithError("failed to create file/folder.", err)
|
||||
}
|
||||
return mutateLogPathIsDir, err
|
||||
}
|
||||
|
@ -345,7 +355,7 @@ func getResourceAccordingToResourcePath(resourcePaths []string, cluster bool, po
|
|||
yamlBytes := []byte(resourceStr)
|
||||
resources, err = common.GetResource(yamlBytes)
|
||||
if err != nil {
|
||||
return resources, sanitizedError.NewWithError("failed to extract the resources", err)
|
||||
return resources, sanitizederror.NewWithError("failed to extract the resources", err)
|
||||
}
|
||||
}
|
||||
} else if (len(resourcePaths) > 0 && resourcePaths[0] != "-") || len(resourcePaths) < 0 || cluster {
|
||||
|
@ -434,7 +444,7 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst
|
|||
} else {
|
||||
err := printMutatedOutput(mutateLogPath, mutateLogPathIsDir, string(yamlEncodedResource), resource.GetName()+"-mutated")
|
||||
if err != nil {
|
||||
return engineResponses, response.EngineResponse{}, sanitizedError.NewWithError("failed to print mutated result", err)
|
||||
return engineResponses, response.EngineResponse{}, sanitizederror.NewWithError("failed to print mutated result", err)
|
||||
}
|
||||
fmt.Printf("\n\nMutation:\nMutation has been applied successfully. Check the files.")
|
||||
}
|
||||
|
@ -503,8 +513,8 @@ func mutatePolices(policies []*v1.ClusterPolicy) ([]*v1.ClusterPolicy, error) {
|
|||
for _, policy := range policies {
|
||||
p, err := common.MutatePolicy(policy, logger)
|
||||
if err != nil {
|
||||
if !sanitizedError.IsErrorSanitized(err) {
|
||||
return nil, sanitizedError.NewWithError("failed to mutate policy.", err)
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return nil, sanitizederror.NewWithError("failed to mutate policy.", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
@ -557,30 +567,30 @@ func createFileOrFolder(mutateLogPath string, mutateLogPathIsDir bool) error {
|
|||
if os.IsNotExist(err) {
|
||||
errDir := os.MkdirAll(folderPath, 0755)
|
||||
if errDir != nil {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("failed to create directory"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("failed to create directory"), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(mutateLogPath, os.O_RDONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("failed to create file"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("failed to create file"), err)
|
||||
}
|
||||
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("failed to close file"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("failed to close file"), err)
|
||||
}
|
||||
|
||||
} else {
|
||||
errDir := os.MkdirAll(mutateLogPath, 0755)
|
||||
if errDir != nil {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("failed to create directory"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("failed to create directory"), err)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return sanitizedError.NewWithError(fmt.Sprintf("failed to describe file"), err)
|
||||
return sanitizederror.NewWithError(fmt.Sprintf("failed to describe file"), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/go-logr/logr"
|
||||
|
@ -22,62 +23,56 @@ import (
|
|||
)
|
||||
|
||||
// GetPolicies - Extracting the policies from multiple YAML
|
||||
func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) {
|
||||
func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, errors []error) {
|
||||
for _, path := range paths {
|
||||
log.Log.V(5).Info("reading policies", "path", path)
|
||||
|
||||
path = filepath.Clean(path)
|
||||
fileDesc, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if fileDesc.IsDir() {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to parse %v", path), err)
|
||||
errors = append(errors, fmt.Errorf("failed to read %v: %v", path, err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
listOfFiles := make([]string, 0)
|
||||
for _, file := range files {
|
||||
listOfFiles = append(listOfFiles, filepath.Join(path, file.Name()))
|
||||
}
|
||||
policiesFromDir, err := GetPolicies(listOfFiles)
|
||||
if err != nil {
|
||||
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to extract policies from %v", listOfFiles), err)
|
||||
}
|
||||
|
||||
policies = append(policies, policiesFromDir...)
|
||||
} else {
|
||||
file, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to load file %v", path), err)
|
||||
}
|
||||
getPolicies, getErrors := utils.GetPolicy(file)
|
||||
var errString string
|
||||
for _, err := range getErrors {
|
||||
if err != nil {
|
||||
errString += err.Error() + "\n"
|
||||
ext := filepath.Ext(file.Name())
|
||||
if ext == "" || ext == ".yaml" || ext == ".yml" {
|
||||
listOfFiles = append(listOfFiles, filepath.Join(path, file.Name()))
|
||||
}
|
||||
}
|
||||
if errString != "" {
|
||||
fmt.Printf("failed to extract policies: %s\n", errString)
|
||||
os.Exit(2)
|
||||
|
||||
policiesFromDir, errorsFromDir := GetPolicies(listOfFiles)
|
||||
errors = append(errors, errorsFromDir...)
|
||||
policies = append(policies, policiesFromDir...)
|
||||
|
||||
} else {
|
||||
fileBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
errors = append(errors, fmt.Errorf("failed to read %v: %v", path, err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
policies = append(policies, getPolicies...)
|
||||
policiesFromFile, errFromFile := utils.GetPolicy(fileBytes)
|
||||
if errFromFile != nil {
|
||||
err := fmt.Errorf("failed to process %s: %v", path, errFromFile.Error())
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
policies = append(policies, policiesFromFile...)
|
||||
}
|
||||
}
|
||||
|
||||
return policies, nil
|
||||
}
|
||||
|
||||
//ValidateAndGetPolicies - validating policies
|
||||
func ValidateAndGetPolicies(policyPaths []string) ([]*v1.ClusterPolicy, error) {
|
||||
policies, err := GetPolicies(policyPaths)
|
||||
if err != nil {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return nil, sanitizederror.NewWithError((fmt.Sprintf("failed to parse %v path/s.", policyPaths)), err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return policies, nil
|
||||
log.Log.V(3).Info("read policies", "policies", len(policies), "errors", len(errors))
|
||||
return policies, errors
|
||||
}
|
||||
|
||||
// PolicyHasVariables - check for variables in the policy
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package sanitizederror
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type customError struct {
|
||||
message string
|
||||
|
@ -10,9 +13,18 @@ func (c customError) Error() string {
|
|||
return c.message
|
||||
}
|
||||
|
||||
// New creates a new sanitized error with given message
|
||||
func New(message string) error {
|
||||
return customError{message: message}
|
||||
func New(msg string) error {
|
||||
return customError{message: msg}
|
||||
}
|
||||
|
||||
func NewWithErrors(message string, errors []error) error {
|
||||
bldr := strings.Builder{}
|
||||
bldr.WriteString(message + "\n")
|
||||
for _, err := range errors {
|
||||
bldr.WriteString(err.Error() + "\n")
|
||||
}
|
||||
|
||||
return customError{message: bldr.String()}
|
||||
}
|
||||
|
||||
// NewWithError creates a new sanitized error with given message and error
|
||||
|
|
|
@ -9,13 +9,13 @@ import (
|
|||
|
||||
v1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/common"
|
||||
sanitizederror "github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
policy2 "github.com/kyverno/kyverno/pkg/policy"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
log "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
yaml "sigs.k8s.io/yaml"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// Command returns validate command
|
||||
|
@ -27,12 +27,10 @@ func Command() *cobra.Command {
|
|||
Short: "Validates kyverno policies",
|
||||
Example: "kyverno validate /path/to/policy.yaml /path/to/folderOfPolicies",
|
||||
RunE: func(cmd *cobra.Command, policyPaths []string) (err error) {
|
||||
log := log.Log
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
log.Error(err, "failed to sanitize")
|
||||
log.Log.Error(err, "failed to sanitize")
|
||||
err = fmt.Errorf("internal error")
|
||||
}
|
||||
}
|
||||
|
@ -58,26 +56,22 @@ func Command() *cobra.Command {
|
|||
}
|
||||
|
||||
yamlBytes := []byte(policyStr)
|
||||
var getErrors []error
|
||||
policies, getErrors = utils.GetPolicy(yamlBytes)
|
||||
var errString string
|
||||
|
||||
for _, err := range getErrors {
|
||||
if err != nil {
|
||||
errString += err.Error() + "\n"
|
||||
}
|
||||
}
|
||||
if errString != "" {
|
||||
return sanitizederror.NewWithError("failed to extract the resources", errors.New(errString))
|
||||
policies, err = utils.GetPolicy(yamlBytes)
|
||||
if err != nil {
|
||||
return sanitizederror.NewWithError("failed to parse policy", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
policies, err = common.ValidateAndGetPolicies(policyPaths)
|
||||
if err != nil {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return sanitizederror.NewWithError("failed to mutate policies.", err)
|
||||
policies, errs := common.GetPolicies(policyPaths)
|
||||
if len(errs) > 0 && len(policies) == 0 {
|
||||
return sanitizederror.NewWithErrors("failed to read policies", errs)
|
||||
}
|
||||
|
||||
if len(errs) > 0 && log.Log.V(1).Enabled() {
|
||||
fmt.Printf("ignoring errors: \n")
|
||||
for _, e := range errs {
|
||||
fmt.Printf(" %v \n", e.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +103,7 @@ func Command() *cobra.Command {
|
|||
} else {
|
||||
fmt.Printf("Policy %s is valid.\n\n", policy.Name)
|
||||
if outputType != "" {
|
||||
logger := log.WithName("validate")
|
||||
logger := log.Log.WithName("validate")
|
||||
p, err := common.MutatePolicy(policy, logger)
|
||||
if err != nil {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
|
|
|
@ -30,9 +30,9 @@ func Test_Exclude(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
policies, errs := utils.GetPolicy(file)
|
||||
if len(errs) != 0 {
|
||||
t.Log(errs)
|
||||
policies, err := utils.GetPolicy(file)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
policy := policies[0]
|
||||
|
@ -61,9 +61,9 @@ func Test_CronJobOnly(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
policies, errs := utils.GetPolicy(file)
|
||||
if len(errs) != 0 {
|
||||
t.Log(errs)
|
||||
policies, err := utils.GetPolicy(file)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
policy := policies[0]
|
||||
|
@ -94,9 +94,9 @@ func Test_CronJob_hasExclude(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
policies, errs := utils.GetPolicy(file)
|
||||
if len(errs) != 0 {
|
||||
t.Log(errs)
|
||||
policies, err := utils.GetPolicy(file)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
policy := policies[0]
|
||||
|
@ -130,9 +130,9 @@ func Test_CronJobAndDeployment(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
policies, errs := utils.GetPolicy(file)
|
||||
if len(errs) != 0 {
|
||||
t.Log(errs)
|
||||
policies, err := utils.GetPolicy(file)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
policy := policies[0]
|
||||
|
|
|
@ -11,35 +11,33 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
// GetPolicy - Extracts policies from a YAML
|
||||
func GetPolicy(file []byte) (clusterPolicies []*v1.ClusterPolicy, errors []error) {
|
||||
policies, err := SplitYAMLDocuments(file)
|
||||
// GetPolicy - extracts policies from YAML bytes
|
||||
func GetPolicy(bytes []byte) (clusterPolicies []*v1.ClusterPolicy, err error) {
|
||||
policies, err := SplitYAMLDocuments(bytes)
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
return clusterPolicies, errors
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, thisPolicyBytes := range policies {
|
||||
policyBytes, err := yaml.ToJSON(thisPolicyBytes)
|
||||
if err != nil {
|
||||
errors = append(errors, fmt.Errorf(fmt.Sprintf("failed to convert json. error: %v", err)))
|
||||
continue
|
||||
return nil, fmt.Errorf("failed to convert to JSON: %v", err)
|
||||
}
|
||||
|
||||
policy := &v1.ClusterPolicy{}
|
||||
if err := json.Unmarshal(policyBytes, policy); err != nil {
|
||||
errors = append(errors, fmt.Errorf(fmt.Sprintf("failed to decode policy. error: %v", err)))
|
||||
continue
|
||||
return nil, fmt.Errorf("failed to decode policy: %v", err)
|
||||
}
|
||||
|
||||
if !(policy.TypeMeta.Kind == "ClusterPolicy" || policy.TypeMeta.Kind == "Policy") {
|
||||
errors = append(errors, fmt.Errorf(fmt.Sprintf("resource %v is not a policy/clusterPolicy", policy.Name)))
|
||||
continue
|
||||
msg := fmt.Sprintf("resource %s/%s is not a Policy or a ClusterPolicy", policy.Kind, policy.Name)
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
|
||||
clusterPolicies = append(clusterPolicies, policy)
|
||||
}
|
||||
|
||||
return clusterPolicies, errors
|
||||
return clusterPolicies, nil
|
||||
}
|
||||
|
||||
// SplitYAMLDocuments reads the YAML bytes per-document, unmarshals the TypeMeta information from each document
|
||||
|
|
|
@ -28,5 +28,5 @@ expected:
|
|||
rules:
|
||||
- name: check-cpu-memory-limits
|
||||
type: Validation
|
||||
message: Validation rule 'check-cpu-memory-limits' succeeded.
|
||||
message: validation rule 'check-cpu-memory-limits' passed.
|
||||
success: true
|
|
@ -15,5 +15,5 @@ expected:
|
|||
rules:
|
||||
- name: validate-default-proc-mount
|
||||
type: Validation
|
||||
message: "Validation rule 'validate-default-proc-mount' succeeded."
|
||||
message: "validation rule 'validate-default-proc-mount' passed."
|
||||
success: true
|
|
@ -14,5 +14,5 @@ expected:
|
|||
rules:
|
||||
- name: prevent-mounting-default-serviceaccount
|
||||
type: Validation
|
||||
message: "Validation error: Prevent mounting of default service account; Validation rule prevent-mounting-default-serviceaccount failed at path /spec/serviceAccountName/"
|
||||
message: "validation error: Prevent mounting of default service account. Rule prevent-mounting-default-serviceaccount failed at path /spec/serviceAccountName/"
|
||||
success: false
|
|
@ -14,9 +14,9 @@ expected:
|
|||
rules:
|
||||
- name: check-readinessProbe-exists
|
||||
type: Validation
|
||||
message: Validation rule 'check-readinessProbe-exists' succeeded.
|
||||
message: validation rule 'check-readinessProbe-exists' passed.
|
||||
success: true
|
||||
- name: check-livenessProbe-exists
|
||||
type: Validation
|
||||
message: Validation rule 'check-livenessProbe-exists' succeeded.
|
||||
message: validation rule 'check-livenessProbe-exists' passed.
|
||||
success: true
|
||||
|
|
|
@ -15,5 +15,5 @@ expected:
|
|||
rules:
|
||||
- name: validate-selinux-options
|
||||
type: Validation
|
||||
message: "Validation error: SELinux level is required; Validation rule validate-selinux-options failed at path /spec/containers/0/securityContext/seLinuxOptions/"
|
||||
message: "validation error: SELinux level is required. Rule validate-selinux-options failed at path /spec/containers/0/securityContext/seLinuxOptions/"
|
||||
success: false
|
|
@ -15,5 +15,5 @@ expected:
|
|||
rules:
|
||||
- name: validate-volumes-whitelist
|
||||
type: Validation
|
||||
message: "Validation rule 'validate-volumes-whitelist' anyPattern[2] succeeded."
|
||||
message: "validation rule 'validate-volumes-whitelist' anyPattern[2] passed."
|
||||
success: true
|
|
@ -14,5 +14,5 @@ expected:
|
|||
rules:
|
||||
- name: validate-docker-sock-mount
|
||||
type: Validation
|
||||
message: "Validation error: Use of the Docker Unix socket is not allowed; Validation rule validate-docker-sock-mount failed at path /spec/volumes/0/hostPath/path/"
|
||||
message: "validation error: Use of the Docker Unix socket is not allowed. Rule validate-docker-sock-mount failed at path /spec/volumes/0/hostPath/path/"
|
||||
success: false
|
|
@ -12,5 +12,5 @@ expected:
|
|||
rules:
|
||||
- name: validate-helm-tiller
|
||||
type: Validation
|
||||
message: "Validation error: Helm Tiller is not allowed; Validation rule validate-helm-tiller failed at path /spec/containers/0/image/"
|
||||
message: "validation error: Helm Tiller is not allowed. Rule validate-helm-tiller failed at path /spec/containers/0/image/"
|
||||
success: false
|
||||
|
|
Loading…
Reference in a new issue