mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
43685aedc2
* types added Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * added secret fetching and client creation Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * codegen Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fixed tests Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * validate target resource scope & namespace settings (#7098) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: mutation code (#7095) * fix: mutation code Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * kuttl tests Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * lazy loading of context vars (#7071) * lazy loading of context vars Signed-off-by: Jim Bugwadia <jim@nirmata.com> * gofumpt Signed-off-by: Jim Bugwadia <jim@nirmata.com> * add kuttl tests Signed-off-by: Jim Bugwadia <jim@nirmata.com> --------- Signed-off-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * moved to policy context Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * removed errors Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * RegistryClientLoader Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * [Feature] Add kuttl tests with policy exceptions disabled (#7117) * added tests Signed-off-by: Ved Ratan <vedratan8@gmail.com> * removed redundant code Signed-off-by: Ved Ratan <vedratan8@gmail.com> * fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> * fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> * typo fix and README changes Signed-off-by: Ved Ratan <vedratan8@gmail.com> * fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> --------- Signed-off-by: Ved Ratan <vedratan8@gmail.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * Conditions message (#7113) * add message to conditions Signed-off-by: Jim Bugwadia <jim@nirmata.com> * add tests Signed-off-by: Jim Bugwadia <jim@nirmata.com> * extend tests Signed-off-by: Jim Bugwadia <jim@nirmata.com> --------- Signed-off-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump zgosalvez/github-actions-ensure-sha-pinned-actions (#7123) Bumps [zgosalvez/github-actions-ensure-sha-pinned-actions](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions) from 2.1.2 to 2.1.3. - [Release notes](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/releases) - [Commits](21991cec25...555a30da26
) --- updated-dependencies: - dependency-name: zgosalvez/github-actions-ensure-sha-pinned-actions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump sigs.k8s.io/kustomize/kyaml from 0.14.1 to 0.14.2 (#7121) Bumps [sigs.k8s.io/kustomize/kyaml](https://github.com/kubernetes-sigs/kustomize) from 0.14.1 to 0.14.2. - [Release notes](https://github.com/kubernetes-sigs/kustomize/releases) - [Commits](https://github.com/kubernetes-sigs/kustomize/compare/kyaml/v0.14.1...kyaml/v0.14.2) --- updated-dependencies: - dependency-name: sigs.k8s.io/kustomize/kyaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump oras.land/oras-go/v2 from 2.0.2 to 2.1.0 (#7102) Bumps [oras.land/oras-go/v2](https://github.com/oras-project/oras-go) from 2.0.2 to 2.1.0. - [Release notes](https://github.com/oras-project/oras-go/releases) - [Commits](https://github.com/oras-project/oras-go/compare/v2.0.2...v2.1.0) --- updated-dependencies: - dependency-name: oras.land/oras-go/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * add condition msg to v2beta1 (#7126) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * feat: print container flags and their values (#7127) * add condition msg to v2beta1 Signed-off-by: ShutingZhao <shuting@nirmata.com> * print flags settings Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * remove the container flag genWorker from the admission controller (#7132) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump google.golang.org/grpc from 1.54.0 to 1.55.0 (#7103) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.54.0 to 1.55.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.54.0...v1.55.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * remove the duplicate entry (#7125) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump sigs.k8s.io/kustomize/api from 0.13.2 to 0.13.3 (#7120) Bumps [sigs.k8s.io/kustomize/api](https://github.com/kubernetes-sigs/kustomize) from 0.13.2 to 0.13.3. - [Release notes](https://github.com/kubernetes-sigs/kustomize/releases) - [Commits](https://github.com/kubernetes-sigs/kustomize/compare/api/v0.13.2...api/v0.13.3) --- updated-dependencies: - dependency-name: sigs.k8s.io/kustomize/api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * update background scan logging messages (#7142) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * Update chart with v2 to v3 migration guidance. (#7144) * add Saxo Bank and Velux as adopters Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update chart README and validations Signed-off-by: Chip Zoller <chipzoller@gmail.com> * codegen Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * add Controller Internals info (#7147) Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * Supporting ValidatingAdmissionPolicy in kyverno cli (apply and test command) (#6656) * feat: add policy reporter to the dev lab Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * refactor: remove obsolete structs from CLI Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * more Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * codegen Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * Supporting ValidatingAdmissionPolicy in kyverno apply Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * chore: bump k8s from v0.26.3 to v0.27.0-rc.0 Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * Support validating admission policy in kyverno apply Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * Support validating admission policy in kyverno test Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * refactoring Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * Adding kyverno apply tests for validating admission policy Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * fix Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * fix Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * running codegen-all Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * fix Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * Adding IsVap field in TestResults Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * chore: bump k8s from v0.27.0-rc.0 to v0.27.1 Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * fix Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * fix Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * Fix vap in engine response Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> * codegen Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump sigs.k8s.io/kustomize/api from 0.13.3 to 0.13.4 (#7150) Bumps [sigs.k8s.io/kustomize/api](https://github.com/kubernetes-sigs/kustomize) from 0.13.3 to 0.13.4. - [Release notes](https://github.com/kubernetes-sigs/kustomize/releases) - [Commits](https://github.com/kubernetes-sigs/kustomize/compare/api/v0.13.3...api/v0.13.4) --- updated-dependencies: - dependency-name: sigs.k8s.io/kustomize/api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump golang.org/x/crypto from 0.8.0 to 0.9.0 (#7149) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.8.0 to 0.9.0. - [Commits](https://github.com/golang/crypto/compare/v0.8.0...v0.9.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * Added `omit-events` flag to allow disabling of event emission (#7010) * added comma seperated flag Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * reason added in logs Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * added requested changes Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * kuttl test init Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * updated kuttl tests Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * updated behavior Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fixed flawed behavior Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * updated test location and added readme Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * tests Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * updated step Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * omit events Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> --------- Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: let reports controller quit when loosing the lead (#7153) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump slsa-framework/slsa-github-generator (#7160) Bumps [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/slsa-framework/slsa-github-generator/releases) - [Changelog](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md) - [Commits](https://github.com/slsa-framework/slsa-github-generator/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: slsa-framework/slsa-github-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore: bump otel deps (#7152) * chore: bump otel deps Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/cloudflare/circl from 1.3.2 to 1.3.3 (#7172) Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/docker/distribution (#7171) Bumps [github.com/docker/distribution](https://github.com/docker/distribution) from 2.8.1+incompatible to 2.8.2+incompatible. - [Release notes](https://github.com/docker/distribution/releases) - [Commits](https://github.com/docker/distribution/compare/v2.8.1...v2.8.2) --- updated-dependencies: - dependency-name: github.com/docker/distribution dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/go-logr/zapr from 1.2.3 to 1.2.4 (#7177) Bumps [github.com/go-logr/zapr](https://github.com/go-logr/zapr) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/go-logr/zapr/releases) - [Commits](https://github.com/go-logr/zapr/compare/v1.2.3...v1.2.4) --- updated-dependencies: - dependency-name: github.com/go-logr/zapr dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * Add refactor note (#7169) Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fixed typo in the v2 to v3 helm migration guide (#7163) * fixed typo in the v2 to v3 helm migration guide Signed-off-by: Richard Parke <richardparke15@gmail.com> * codegen Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Richard Parke <richardparke15@gmail.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/distribution/distribution (#7178) Bumps [github.com/distribution/distribution](https://github.com/distribution/distribution) from 2.8.1+incompatible to 2.8.2+incompatible. - [Release notes](https://github.com/distribution/distribution/releases) - [Commits](https://github.com/distribution/distribution/compare/v2.8.1...v2.8.2) --- updated-dependencies: - dependency-name: github.com/distribution/distribution dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * tweaks (#7166) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * feat: add logging feature to helm chart (#7181) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * refactor: hide json context from caller (#7139) * refactor: hide json context from caller Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * unit tests Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * feat: add omit-events feature in helm chart (#7185) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: preconditions in mutate existing rules (#7183) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: use structured jsonpatch instead of byte arrays (#7186) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * added secret lister Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * changes from review Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * added rclientloader to policy context Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * refactor changes Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * NIT Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * added RegistryClientLoaderNewOrDie to policy context Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * CI fixes Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: panic for policy variable validation (#7079) * fix panic Signed-off-by: ShutingZhao <shuting@nirmata.com> * check errors Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: remove policy-reporter from dev lab (#7196) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: cleanup controller metrics name (#7198) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: http request metrics (#7197) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * remove unused code (#7203) Signed-off-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * handle Deny rules where conditions eval to true (#7204) Signed-off-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * [Bug] Enforce message wrong (#7208) * fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> * fixed tests Signed-off-by: Ved Ratan <vedratan8@gmail.com> --------- Signed-off-by: Ved Ratan <vedratan8@gmail.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump codecov/codecov-action from 3.1.3 to 3.1.4 (#7207) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](894ff025c7...eaaf4bedf3
) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump sigstore/cosign-installer from 3.0.3 to 3.0.4 (#7215) Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.0.3 to 3.0.4. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](204a51a57a...03d0fecf17
) --- updated-dependencies: - dependency-name: sigstore/cosign-installer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: panic in reports controller (#7220) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: mutate existing auth check (#7219) * fix auth check when using variables in ns Signed-off-by: ShutingZhao <shuting@nirmata.com> * add kuttl tests Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: do not exclude kube-system service accounts by default (#7225) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * docs: add reports system design doc (#6949) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump k8s.io/apimachinery from 0.27.1 to 0.27.2 (#7227) Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.27.1 to 0.27.2. - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.27.1...v0.27.2) --- updated-dependencies: - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: shuting <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump k8s.io/cli-runtime from 0.27.1 to 0.27.2 (#7228) Bumps [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) from 0.27.1 to 0.27.2. - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.27.1...v0.27.2) --- updated-dependencies: - dependency-name: k8s.io/cli-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump sigstore/cosign-installer from 3.0.4 to 3.0.5 (#7229) Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.0.4 to 3.0.5. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](03d0fecf17...dd6b2e2b61
) --- updated-dependencies: - dependency-name: sigstore/cosign-installer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump k8s.io/pod-security-admission from 0.27.1 to 0.27.2 (#7232) Bumps [k8s.io/pod-security-admission](https://github.com/kubernetes/pod-security-admission) from 0.27.1 to 0.27.2. - [Commits](https://github.com/kubernetes/pod-security-admission/compare/v0.27.1...v0.27.2) --- updated-dependencies: - dependency-name: k8s.io/pod-security-admission dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: match logic misbehave (#7218) * add rule name in ur for mutate existing Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix match logic Signed-off-by: ShutingZhao <shuting@nirmata.com> * linter fixes Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix the match logic to only apply to the new object, unless it's a delete request Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/stretchr/testify from 1.8.2 to 1.8.3 (#7240) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.3. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.3) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/onsi/gomega from 1.27.6 to 1.27.7 (#7239) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.27.6 to 1.27.7. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.27.6...v1.27.7) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump k8s.io/kube-aggregator from 0.27.1 to 0.27.2 (#7241) Bumps [k8s.io/kube-aggregator](https://github.com/kubernetes/kube-aggregator) from 0.27.1 to 0.27.2. - [Commits](https://github.com/kubernetes/kube-aggregator/compare/v0.27.1...v0.27.2) --- updated-dependencies: - dependency-name: k8s.io/kube-aggregator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump k8s.io/apiextensions-apiserver from 0.27.1 to 0.27.2 (#7242) Bumps [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) from 0.27.1 to 0.27.2. - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.27.1...v0.27.2) --- updated-dependencies: - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * passing rclientloader directly Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * lazy evaluate vars in conditions (#7238) * lazy evaluate vars in conditions Signed-off-by: Jim Bugwadia <jim@nirmata.com> * remove unnecessary conversion Signed-off-by: Jim Bugwadia <jim@nirmata.com> * fix test Signed-off-by: Jim Bugwadia <jim@nirmata.com> * Update test/conformance/kuttl/validate/clusterpolicy/standard/variables/lazyload/conditions/03-manifests.yaml Signed-off-by: shuting <shutting06@gmail.com> * Update test/conformance/kuttl/validate/clusterpolicy/standard/variables/lazyload/README.md Signed-off-by: shuting <shutting06@gmail.com> * added error check in test Signed-off-by: Jim Bugwadia <jim@nirmata.com> --------- Signed-off-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: shuting <shutting06@gmail.com> Co-authored-by: shuting <shutting06@gmail.com> Co-authored-by: kyverno-bot <104836976+kyverno-bot@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * quote image in error (#7259) Signed-off-by: bakito <github@bakito.ch> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix: auto update webhooks not configuring fail endpoint (#7261) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * fix latest version check (#7263) Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump svenstaro/upload-release-action from 2.5.0 to 2.6.0 (#7270) Bumps [svenstaro/upload-release-action](https://github.com/svenstaro/upload-release-action) from 2.5.0 to 2.6.0. - [Release notes](https://github.com/svenstaro/upload-release-action/releases) - [Changelog](https://github.com/svenstaro/upload-release-action/blob/master/CHANGELOG.md) - [Commits](7319e4733e...58d5258088
) --- updated-dependencies: - dependency-name: svenstaro/upload-release-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump sigs.k8s.io/controller-runtime from 0.14.6 to 0.15.0 (#7272) Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.14.6 to 0.15.0. - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.14.6...v0.15.0) --- updated-dependencies: - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add yaml util to check empty document (#7276) Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * chore(deps): bump github.com/go-git/go-git/v5 from 5.6.1 to 5.7.0 (#7274) Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.6.1...v5.7.0) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * NIT Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * Azure to ACR Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * go mod fix Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * codegen Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * NIT Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * adding kuttl test Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * use pointer Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fixes Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * cleanup Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * global client Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * cleanup Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * added kubeclient Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * added nil kubeclient check Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> * context Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * factory Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * more fixes Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * secrets lister Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * flags Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * tests Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix cli Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix kuttl test Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix kuttl test Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix kuttl test Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * kuttl test Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * factories Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: Ved Ratan <vedratan8@gmail.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: Mariam Fahmy <mariamfahmy66@gmail.com> Signed-off-by: Richard Parke <richardparke15@gmail.com> Signed-off-by: shuting <shutting06@gmail.com> Signed-off-by: bakito <github@bakito.ch> Co-authored-by: shuting <shuting@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: Ved Ratan <82467006+VedRatan@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chip Zoller <chipzoller@gmail.com> Co-authored-by: Mariam Fahmy <55502281+MariamFahmy98@users.noreply.github.com> Co-authored-by: rparke <50015370+rparke@users.noreply.github.com> Co-authored-by: shuting <shutting06@gmail.com> Co-authored-by: kyverno-bot <104836976+kyverno-bot@users.noreply.github.com> Co-authored-by: Marc Brugger <github@bakito.ch>
2400 lines
60 KiB
Go
2400 lines
60 KiB
Go
package engine
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
|
client "github.com/kyverno/kyverno/pkg/clients/dclient"
|
|
"github.com/kyverno/kyverno/pkg/config"
|
|
"github.com/kyverno/kyverno/pkg/engine/adapters"
|
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
|
"github.com/kyverno/kyverno/pkg/engine/factories"
|
|
enginetest "github.com/kyverno/kyverno/pkg/engine/test"
|
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
|
"github.com/stretchr/testify/require"
|
|
"gotest.tools/assert"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
)
|
|
|
|
func testMutate(
|
|
ctx context.Context,
|
|
client client.Interface,
|
|
rclient registryclient.Client,
|
|
pContext *PolicyContext,
|
|
contextLoader engineapi.ContextLoaderFactory,
|
|
) engineapi.EngineResponse {
|
|
if contextLoader == nil {
|
|
contextLoader = factories.DefaultContextLoaderFactory(nil)
|
|
}
|
|
e := NewEngine(
|
|
cfg,
|
|
config.NewDefaultMetricsConfiguration(),
|
|
jp,
|
|
adapters.Client(client),
|
|
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
|
|
contextLoader,
|
|
nil,
|
|
"",
|
|
)
|
|
return e.Mutate(
|
|
ctx,
|
|
pContext,
|
|
)
|
|
}
|
|
|
|
func loadResource[T any](t *testing.T, bytes []byte) T {
|
|
var result T
|
|
require.NoError(t, json.Unmarshal(bytes, &result))
|
|
return result
|
|
}
|
|
|
|
func loadUnstructured(t *testing.T, bytes []byte) unstructured.Unstructured {
|
|
var resource unstructured.Unstructured
|
|
require.NoError(t, resource.UnmarshalJSON(bytes))
|
|
return resource
|
|
}
|
|
|
|
func createContext(t *testing.T, policy kyverno.PolicyInterface, resource unstructured.Unstructured, operation kyverno.AdmissionOperation) *PolicyContext {
|
|
ctx, err := NewPolicyContext(
|
|
jp,
|
|
resource,
|
|
kyverno.Create,
|
|
nil,
|
|
cfg,
|
|
)
|
|
require.NoError(t, err)
|
|
return ctx.WithPolicy(policy)
|
|
}
|
|
|
|
func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "add-label"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "add-name-label",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"appname": "{{request.object.metadata.name}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "check-root-user"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "check-root-user",
|
|
"image": "nginxinc/nginx-unprivileged",
|
|
"securityContext": {
|
|
"runAsNonRoot": true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
require.Equal(t, 1, len(er.PolicyResponse.Rules))
|
|
|
|
patched := er.PatchedResource
|
|
require.NotEqual(t, resource, patched)
|
|
unstructured.SetNestedField(resource.UnstructuredContent(), "check-root-user", "metadata", "labels", "appname")
|
|
require.Equal(t, resource, patched)
|
|
}
|
|
|
|
func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "check-root-user"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "check-root-user",
|
|
"image": "nginxinc/nginx-unprivileged",
|
|
"securityContext": {
|
|
"runAsNonRoot": true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "substitute-variable"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "test-path-not-exist",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"name": "{{request.object.metadata.name1}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
|
|
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message(), "Unknown key \"name1\" in path"))
|
|
}
|
|
|
|
func Test_variableSubstitutionCLI(t *testing.T) {
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "nginx-config-test"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "nginx:latest",
|
|
"name": "test-nginx"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "cm-variable-example"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "example-configmap-lookup",
|
|
"context": [
|
|
{
|
|
"name": "dictionary",
|
|
"configMap": {
|
|
"name": "mycmap",
|
|
"namespace": "default"
|
|
}
|
|
}
|
|
],
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"my-environment-name": "{{dictionary.data.env}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(
|
|
context.TODO(),
|
|
nil,
|
|
registryclient.NewOrDie(),
|
|
policyContext,
|
|
enginetest.ContextLoaderFactory(
|
|
nil,
|
|
map[string]enginetest.Policy{
|
|
"cm-variable-example": {
|
|
Rules: map[string]enginetest.Rule{
|
|
"example-configmap-lookup": {
|
|
Values: map[string]interface{}{
|
|
"dictionary.data.env": "dev1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
),
|
|
)
|
|
require.Equal(t, 1, len(er.PolicyResponse.Rules))
|
|
|
|
patched := er.PatchedResource
|
|
require.NotEqual(t, resource, patched)
|
|
unstructured.SetNestedField(resource.UnstructuredContent(), "dev1", "metadata", "labels", "my-environment-name")
|
|
require.Equal(t, resource, patched)
|
|
}
|
|
|
|
// https://github.com/kyverno/kyverno/issues/2022
|
|
func Test_chained_rules(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "replace-image-registry",
|
|
"annotations": {
|
|
"policies.kyverno.io/minversion": "1.4.2"
|
|
}
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "replace-image-registry",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"(name)": "*",
|
|
"image": "{{regex_replace_all('^([^/]+\\.[^/]+/)?(.*)$','{{@}}','myregistry.corp.com/$2')}}"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "replace-image-registry-chained",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"(name)": "*",
|
|
"image": "{{regex_replace_all('\\b(myregistry.corp.com)\\b','{{@}}','otherregistry.corp.com')}}"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "test"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "test",
|
|
"image": "foo/bash:5.0"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
require.Equal(t, 2, len(er.PolicyResponse.Rules))
|
|
|
|
patched := er.PatchedResource
|
|
require.NotEqual(t, resource, patched)
|
|
|
|
containers, found, err := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", "containers")
|
|
require.NoError(t, err)
|
|
require.True(t, found)
|
|
require.NotNil(t, containers)
|
|
unstructured.SetNestedField(containers[0].(map[string]interface{}), "otherregistry.corp.com/foo/bash:5.0", "image")
|
|
unstructured.SetNestedSlice(resource.UnstructuredContent(), containers, "spec", "containers")
|
|
require.Equal(t, resource, patched)
|
|
}
|
|
|
|
func Test_precondition(t *testing.T) {
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "nginx-config-test",
|
|
"labels": {
|
|
"app.kubernetes.io/managed-by": "Helm"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "nginx:latest",
|
|
"name": "test-nginx"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "cm-variable-example"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "example-configmap-lookup",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"preconditions": [
|
|
{
|
|
"key": "{{ request.object.metadata.labels.\"app.kubernetes.io/managed-by\"}}",
|
|
"operator": "Equals",
|
|
"value": "Helm"
|
|
}
|
|
],
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"my-added-label": "test"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, enginetest.ContextLoaderFactory(nil, nil))
|
|
require.Equal(t, 1, len(er.PolicyResponse.Rules))
|
|
|
|
patched := er.PatchedResource
|
|
require.NotEqual(t, resource, patched)
|
|
unstructured.SetNestedField(resource.UnstructuredContent(), "test", "metadata", "labels", "my-added-label")
|
|
require.Equal(t, resource, patched)
|
|
}
|
|
|
|
func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Endpoints",
|
|
"metadata": {
|
|
"name": "my-service"
|
|
},
|
|
"subsets": [
|
|
{
|
|
"addresses": [
|
|
{
|
|
"ip": "127.0.0.1"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}`)
|
|
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "policy-endpoints"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "Add IP to subset",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Endpoints"
|
|
]
|
|
}
|
|
},
|
|
"preconditions": [
|
|
{
|
|
"key": "{{ request.object.subsets[] | length(@) }}",
|
|
"operator": "Equals",
|
|
"value": "1"
|
|
}
|
|
],
|
|
"mutate": {
|
|
"patchesJson6902": "- path: \"/subsets/0/addresses/-\"\n op: add\n value: {\"ip\":\"192.168.42.172\"}"
|
|
}
|
|
},
|
|
{
|
|
"name": "Add IP to subsets",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Endpoints"
|
|
]
|
|
}
|
|
},
|
|
"preconditions": [
|
|
{
|
|
"key": "{{ request.object.subsets[] | length(@) }}",
|
|
"operator": "Equals",
|
|
"value": "2"
|
|
}
|
|
],
|
|
"mutate": {
|
|
"patchesJson6902": "- path: \"/subsets/0/addresses/-\"\n op: add\n value: {\"ip\":\"192.168.42.172\"}\n- path: \"/subsets/1/addresses/-\"\n op: add\n value: {\"ip\":\"192.168.42.173\"}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
policy := loadResource[kyverno.ClusterPolicy](t, []byte(policyRaw))
|
|
resource := loadUnstructured(t, []byte(resourceRaw))
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, enginetest.ContextLoaderFactory(nil, nil))
|
|
require.Equal(t, 2, len(er.PolicyResponse.Rules))
|
|
|
|
patched := er.PatchedResource
|
|
require.NotEqual(t, resource, patched)
|
|
|
|
subsetsField, found, err := unstructured.NestedFieldNoCopy(resource.UnstructuredContent(), "subsets")
|
|
require.NoError(t, err)
|
|
require.True(t, found)
|
|
require.NotNil(t, subsetsField)
|
|
|
|
subsets, ok := subsetsField.([]interface{})
|
|
require.True(t, ok)
|
|
require.NotNil(t, subsets)
|
|
|
|
addressesField, found, err := unstructured.NestedFieldNoCopy(subsets[0].(map[string]interface{}), "addresses")
|
|
require.NoError(t, err)
|
|
require.True(t, found)
|
|
require.NotNil(t, addressesField)
|
|
|
|
addresses, ok := addressesField.([]interface{})
|
|
require.True(t, ok)
|
|
require.NotNil(t, addresses)
|
|
|
|
addresses = append(addresses, map[string]interface{}{"ip": "192.168.42.172"})
|
|
unstructured.SetNestedSlice(subsets[0].(map[string]interface{}), addresses, "addresses")
|
|
|
|
require.Equal(t, resource, patched)
|
|
}
|
|
|
|
func Test_foreach(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "replace-image-registry"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "replace-image-registry",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.containers",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "{{ element.name }}",
|
|
"image": "registry.io/{{images.containers.{{element.name}}.path}}:{{images.containers.{{element.name}}.tag}}"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "test"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "test1",
|
|
"image": "foo1/bash1:5.0"
|
|
},
|
|
{
|
|
"name": "test2",
|
|
"image": "foo2/bash2:5.0"
|
|
},
|
|
{
|
|
"name": "test3",
|
|
"image": "foo3/bash3:5.0"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
var policy kyverno.ClusterPolicy
|
|
err := json.Unmarshal(policyRaw, &policy)
|
|
assert.NilError(t, err)
|
|
|
|
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
|
assert.NilError(t, err)
|
|
|
|
policyContext, err := NewPolicyContext(
|
|
jp,
|
|
*resource,
|
|
kyverno.Create,
|
|
nil,
|
|
cfg,
|
|
)
|
|
assert.NilError(t, err)
|
|
policyContext = policyContext.WithPolicy(&policy)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
|
|
|
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
|
assert.NilError(t, err)
|
|
for _, c := range containers {
|
|
ctnr := c.(map[string]interface{})
|
|
switch ctnr["name"] {
|
|
case "test1":
|
|
assert.Equal(t, ctnr["image"], "registry.io/foo1/bash1:5.0")
|
|
case "test2":
|
|
assert.Equal(t, ctnr["image"], "registry.io/foo2/bash2:5.0")
|
|
case "test3":
|
|
assert.Equal(t, ctnr["image"], "registry.io/foo3/bash3:5.0")
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_foreach_element_mutation(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "mutate-privileged"
|
|
},
|
|
"spec": {
|
|
"validationFailureAction": "audit",
|
|
"background": false,
|
|
"webhookTimeoutSeconds": 10,
|
|
"failurePolicy": "Fail",
|
|
"rules": [
|
|
{
|
|
"name": "set-privileged",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.containers",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"(name)": "{{ element.name }}",
|
|
"securityContext": {
|
|
"privileged": false
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "nginx"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "nginx1",
|
|
"image": "nginx"
|
|
},
|
|
{
|
|
"name": "nginx2",
|
|
"image": "nginx"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
var policy kyverno.ClusterPolicy
|
|
err := json.Unmarshal(policyRaw, &policy)
|
|
assert.NilError(t, err)
|
|
|
|
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
|
assert.NilError(t, err)
|
|
|
|
policyContext, err := NewPolicyContext(
|
|
jp,
|
|
*resource,
|
|
kyverno.Create,
|
|
nil,
|
|
cfg,
|
|
)
|
|
assert.NilError(t, err)
|
|
policyContext = policyContext.WithPolicy(&policy)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
|
|
|
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
|
assert.NilError(t, err)
|
|
for _, c := range containers {
|
|
ctnr := c.(map[string]interface{})
|
|
_securityContext, ok := ctnr["securityContext"]
|
|
assert.Assert(t, ok)
|
|
|
|
securityContext := _securityContext.(map[string]interface{})
|
|
assert.Equal(t, securityContext["privileged"], false)
|
|
}
|
|
}
|
|
|
|
func Test_Container_InitContainer_foreach(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "prepend-registry",
|
|
"annotations": {
|
|
"pod-policies.kyverno.io/autogen-controllers": "none"
|
|
}
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "prepend-registry-containers",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.containers",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "{{ element.name }}",
|
|
"image": "registry.io/{{ images.containers.\"{{element.name}}\".path}}:{{images.containers.\"{{element.name}}\".tag}}"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"list": "request.object.spec.initContainers",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"initContainers": [
|
|
{
|
|
"name": "{{ element.name }}",
|
|
"image": "registry.io/{{ images.initContainers.\"{{element.name}}\".name}}:{{images.initContainers.\"{{element.name}}\".tag}}"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "mypod"
|
|
},
|
|
"spec": {
|
|
"automountServiceAccountToken": false,
|
|
"initContainers": [
|
|
{
|
|
"name": "alpine",
|
|
"image": "alpine:latest"
|
|
},
|
|
{
|
|
"name": "busybox",
|
|
"image": "busybox:1.28"
|
|
}
|
|
],
|
|
"containers": [
|
|
{
|
|
"name": "nginx",
|
|
"image": "nginx:1.2.3"
|
|
},
|
|
{
|
|
"name": "redis",
|
|
"image": "redis:latest"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
var policy kyverno.ClusterPolicy
|
|
err := json.Unmarshal(policyRaw, &policy)
|
|
assert.NilError(t, err)
|
|
|
|
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
|
assert.NilError(t, err)
|
|
|
|
policyContext, err := NewPolicyContext(
|
|
jp,
|
|
*resource,
|
|
kyverno.Create,
|
|
nil,
|
|
cfg,
|
|
)
|
|
assert.NilError(t, err)
|
|
policyContext = policyContext.WithPolicy(&policy)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
|
|
|
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
|
assert.NilError(t, err)
|
|
for _, c := range containers {
|
|
ctnr := c.(map[string]interface{})
|
|
switch ctnr["name"] {
|
|
case "alpine":
|
|
assert.Equal(t, ctnr["image"], "registry.io/alpine:latest")
|
|
case "busybox":
|
|
assert.Equal(t, ctnr["image"], "registry.io/busybox:1.28")
|
|
}
|
|
}
|
|
|
|
initContainers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "initContainers")
|
|
assert.NilError(t, err)
|
|
for _, c := range initContainers {
|
|
ctnr := c.(map[string]interface{})
|
|
switch ctnr["name"] {
|
|
case "nginx":
|
|
assert.Equal(t, ctnr["image"], "registry.io/nginx:1.2.3")
|
|
case "redis":
|
|
assert.Equal(t, ctnr["image"], "registry.io/redis:latest")
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_foreach_order_mutation_(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "replace-image"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "replace-image",
|
|
"match": {
|
|
"all": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.containers",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"(name)": "{{ element.name }}",
|
|
"image": "replaced"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "mongodb",
|
|
"labels": {
|
|
"app": "mongodb"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "docker.io/mongo:5.0.3",
|
|
"name": "mongod"
|
|
},
|
|
{
|
|
"image": "nginx",
|
|
"name": "nginx"
|
|
},
|
|
{
|
|
"image": "nginx",
|
|
"name": "nginx3"
|
|
},
|
|
{
|
|
"image": "quay.io/mongodb/mongodb-agent:11.0.5.6963-1",
|
|
"name": "mongodb-agent"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
|
|
|
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
|
assert.NilError(t, err)
|
|
|
|
for i, c := range containers {
|
|
ctnr := c.(map[string]interface{})
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, ctnr["name"], "mongod")
|
|
case 1:
|
|
assert.Equal(t, ctnr["name"], "nginx")
|
|
case 3:
|
|
assert.Equal(t, ctnr["name"], "mongodb-agent")
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_patchStrategicMerge_descending(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "replace-image"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "replace-image",
|
|
"match": {
|
|
"all": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.containers",
|
|
"order": "Descending",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"(name)": "{{ element.name }}",
|
|
"image": "replaced"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "mongodb",
|
|
"labels": {
|
|
"app": "mongodb"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "docker.io/mongo:5.0.3",
|
|
"name": "mongod"
|
|
},
|
|
{
|
|
"image": "nginx",
|
|
"name": "nginx"
|
|
},
|
|
{
|
|
"image": "nginx",
|
|
"name": "nginx3"
|
|
},
|
|
{
|
|
"image": "quay.io/mongodb/mongodb-agent:11.0.5.6963-1",
|
|
"name": "mongodb-agent"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
|
|
|
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
|
assert.NilError(t, err)
|
|
|
|
for i, c := range containers {
|
|
ctnr := c.(map[string]interface{})
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, ctnr["name"], "mongod")
|
|
case 1:
|
|
assert.Equal(t, ctnr["name"], "nginx")
|
|
case 3:
|
|
assert.Equal(t, ctnr["name"], "mongodb-agent")
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_patchStrategicMerge_ascending(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "replace-image"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "replace-image",
|
|
"match": {
|
|
"all": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.containers",
|
|
"order": "Ascending",
|
|
"patchStrategicMerge": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"(name)": "{{ element.name }}",
|
|
"image": "replaced"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "mongodb",
|
|
"labels": {
|
|
"app": "mongodb"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "docker.io/mongo:5.0.3",
|
|
"name": "mongod"
|
|
},
|
|
{
|
|
"image": "nginx",
|
|
"name": "nginx"
|
|
},
|
|
{
|
|
"image": "nginx",
|
|
"name": "nginx3"
|
|
},
|
|
{
|
|
"image": "quay.io/mongodb/mongodb-agent:11.0.5.6963-1",
|
|
"name": "mongodb-agent"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass)
|
|
|
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
|
assert.NilError(t, err)
|
|
|
|
for i, c := range containers {
|
|
ctnr := c.(map[string]interface{})
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, ctnr["name"], "mongodb-agent")
|
|
case 1:
|
|
assert.Equal(t, ctnr["name"], "nginx3")
|
|
case 3:
|
|
assert.Equal(t, ctnr["name"], "mongod")
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_mutate_nested_foreach(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "replace-image-registry"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "replace-dns-suffix",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Ingress"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"foreach": [
|
|
{
|
|
"list": "request.object.spec.tls",
|
|
"foreach": [
|
|
{
|
|
"list": "element.hosts",
|
|
"patchesJson6902": "- path: /spec/tls/{{elementIndex0}}/hosts/{{elementIndex1}}\n op: replace\n value: {{replace_all('{{element}}', '.foo.com', '.newfoo.com')}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "networking.k8s.io/v1",
|
|
"kind": "Ingress",
|
|
"metadata": {
|
|
"name": "tls-example-ingress"
|
|
},
|
|
"spec": {
|
|
"tls": [
|
|
{
|
|
"hosts": [
|
|
"https-example.foo.com"
|
|
],
|
|
"secretName": "testsecret-tls"
|
|
},
|
|
{
|
|
"hosts": [
|
|
"https-example2.foo.com"
|
|
],
|
|
"secretName": "testsecret-tls-2"
|
|
}
|
|
],
|
|
"rules": [
|
|
{
|
|
"host": "https-example.foo.com",
|
|
"http": {
|
|
"paths": [
|
|
{
|
|
"path": "/",
|
|
"pathType": "Prefix",
|
|
"backend": {
|
|
"service": {
|
|
"name": "service1",
|
|
"port": {
|
|
"number": 80
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"host": "https-example2.foo.com",
|
|
"http": {
|
|
"paths": [
|
|
{
|
|
"path": "/",
|
|
"pathType": "Prefix",
|
|
"backend": {
|
|
"service": {
|
|
"name": "service2",
|
|
"port": {
|
|
"number": 80
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
expectedRaw := []byte(`{
|
|
"apiVersion": "networking.k8s.io/v1",
|
|
"kind": "Ingress",
|
|
"metadata": {
|
|
"name": "tls-example-ingress"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"host": "https-example.foo.com",
|
|
"http": {
|
|
"paths": [
|
|
{
|
|
"backend": {
|
|
"service": {
|
|
"name": "service1",
|
|
"port": {
|
|
"number": 80
|
|
}
|
|
}
|
|
},
|
|
"path": "/",
|
|
"pathType": "Prefix"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"host": "https-example2.foo.com",
|
|
"http": {
|
|
"paths": [
|
|
{
|
|
"backend": {
|
|
"service": {
|
|
"name": "service2",
|
|
"port": {
|
|
"number": 80
|
|
}
|
|
}
|
|
},
|
|
"path": "/",
|
|
"pathType": "Prefix"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"tls": [
|
|
{
|
|
"hosts": [
|
|
"https-example.newfoo.com"
|
|
],
|
|
"secretName": "testsecret-tls"
|
|
},
|
|
{
|
|
"hosts": [
|
|
"https-example2.newfoo.com"
|
|
],
|
|
"secretName": "testsecret-tls-2"
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
|
resource := loadUnstructured(t, resourceRaw)
|
|
expected := loadUnstructured(t, expectedRaw)
|
|
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
require.Equal(t, 1, len(er.PolicyResponse.Rules))
|
|
require.Equal(t, engineapi.RuleStatusPass, er.PolicyResponse.Rules[0].Status())
|
|
|
|
patched := er.PatchedResource
|
|
require.Equal(t, expected, patched)
|
|
}
|
|
|
|
func Test_mutate_existing_resources(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
policy []byte
|
|
trigger []byte
|
|
targets [][]byte
|
|
patchedTargets [][]byte
|
|
targetList string
|
|
}{
|
|
{
|
|
name: "test-different-trigger-target",
|
|
policy: []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "test-post-mutation"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "mutate-deploy-on-configmap-update",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"ConfigMap"
|
|
],
|
|
"names": [
|
|
"dictionary"
|
|
],
|
|
"namespaces": [
|
|
"staging"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"preconditions": {
|
|
"any": [
|
|
{
|
|
"key": "{{ request.object.data.foo }}",
|
|
"operator": "Equals",
|
|
"value": "bar"
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"targets": [
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "Deployment",
|
|
"name": "example-A",
|
|
"namespace": "staging"
|
|
}
|
|
],
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"foo": "bar"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`),
|
|
trigger: []byte(`{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"foo": "bar"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "dictionary",
|
|
"namespace": "staging"
|
|
}
|
|
}`),
|
|
targets: [][]byte{[]byte(`{
|
|
"apiVersion": "apps/v1",
|
|
"kind": "Deployment",
|
|
"metadata": {
|
|
"name": "example-A",
|
|
"namespace": "staging",
|
|
"labels": {
|
|
"app": "nginx"
|
|
}
|
|
},
|
|
"spec": {
|
|
"replicas": 1,
|
|
"selector": {
|
|
"matchLabels": {
|
|
"app": "nginx"
|
|
}
|
|
},
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "nginx"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "nginx",
|
|
"image": "nginx:1.14.2",
|
|
"ports": [
|
|
{
|
|
"containerPort": 80
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}`)},
|
|
patchedTargets: [][]byte{[]byte(`{
|
|
"apiVersion": "apps/v1",
|
|
"kind": "Deployment",
|
|
"metadata": {
|
|
"name": "example-A",
|
|
"namespace": "staging",
|
|
"labels": {
|
|
"app": "nginx",
|
|
"foo": "bar"
|
|
}
|
|
},
|
|
"spec": {
|
|
"replicas": 1,
|
|
"selector": {
|
|
"matchLabels": {
|
|
"app": "nginx"
|
|
}
|
|
},
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "nginx"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "nginx",
|
|
"image": "nginx:1.14.2",
|
|
"ports": [
|
|
{
|
|
"containerPort": 80
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}`)},
|
|
targetList: "DeploymentList",
|
|
},
|
|
{
|
|
name: "test-same-trigger-target",
|
|
policy: []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "test-post-mutation"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "mutate-deploy-on-configmap-update",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"ConfigMap"
|
|
],
|
|
"names": [
|
|
"dictionary"
|
|
],
|
|
"namespaces": [
|
|
"staging"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"preconditions": {
|
|
"any": [
|
|
{
|
|
"key": "{{ request.object.data.foo }}",
|
|
"operator": "Equals",
|
|
"value": "bar"
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"targets": [
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"name": "dictionary",
|
|
"namespace": "staging"
|
|
}
|
|
],
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"foo": "bar"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`),
|
|
trigger: []byte(`{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"foo": "bar"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "dictionary",
|
|
"namespace": "staging"
|
|
}
|
|
}`),
|
|
targets: [][]byte{[]byte(`{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"foo": "bar"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "dictionary",
|
|
"namespace": "staging"
|
|
}
|
|
}`)},
|
|
patchedTargets: [][]byte{[]byte(`{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"foo": "bar"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "dictionary",
|
|
"namespace": "staging",
|
|
"labels": {
|
|
"foo": "bar"
|
|
}
|
|
}
|
|
}`)},
|
|
targetList: "ComfigMapList",
|
|
},
|
|
{
|
|
name: "test-in-place-variable",
|
|
policy: []byte(`
|
|
{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "sync-cms"
|
|
},
|
|
"spec": {
|
|
"mutateExistingOnPolicyUpdate": false,
|
|
"rules": [
|
|
{
|
|
"name": "concat-cm",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"ConfigMap"
|
|
],
|
|
"names": [
|
|
"cmone"
|
|
],
|
|
"namespaces": [
|
|
"foo"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"targets": [
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"name": "cmtwo",
|
|
"namespace": "bar"
|
|
}
|
|
],
|
|
"patchStrategicMerge": {
|
|
"data": {
|
|
"keytwo": "{{@}}-{{request.object.data.keyone}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
`),
|
|
trigger: []byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"keyone": "valueone"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmone",
|
|
"namespace": "foo"
|
|
}
|
|
}
|
|
`),
|
|
targets: [][]byte{[]byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"keytwo": "valuetwo"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmtwo",
|
|
"namespace": "bar"
|
|
}
|
|
}
|
|
`)},
|
|
patchedTargets: [][]byte{[]byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"keytwo": "valuetwo-valueone"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmtwo",
|
|
"namespace": "bar"
|
|
}
|
|
}
|
|
`)},
|
|
targetList: "ComfigMapList",
|
|
},
|
|
{
|
|
name: "test-in-place-variable",
|
|
policy: []byte(`
|
|
{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "sync-cms"
|
|
},
|
|
"spec": {
|
|
"mutateExistingOnPolicyUpdate": false,
|
|
"rules": [
|
|
{
|
|
"name": "concat-cm",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"ConfigMap"
|
|
],
|
|
"names": [
|
|
"cmone"
|
|
],
|
|
"namespaces": [
|
|
"foo"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"targets": [
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"name": "cmtwo",
|
|
"namespace": "bar"
|
|
},
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "ConfigMap",
|
|
"name": "cmthree",
|
|
"namespace": "bar"
|
|
}
|
|
],
|
|
"patchStrategicMerge": {
|
|
"data": {
|
|
"key": "{{@}}-{{request.object.data.keyone}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
`),
|
|
trigger: []byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"keyone": "valueone"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmone",
|
|
"namespace": "foo"
|
|
}
|
|
}
|
|
`),
|
|
targets: [][]byte{
|
|
[]byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"key": "valuetwo"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmtwo",
|
|
"namespace": "bar"
|
|
}
|
|
}
|
|
`),
|
|
[]byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"key": "valuethree"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmthree",
|
|
"namespace": "bar"
|
|
}
|
|
}
|
|
`),
|
|
},
|
|
patchedTargets: [][]byte{
|
|
[]byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"key": "valuetwo-valueone"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmtwo",
|
|
"namespace": "bar"
|
|
}
|
|
}
|
|
`),
|
|
[]byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"data": {
|
|
"key": "valuethree-valueone"
|
|
},
|
|
"kind": "ConfigMap",
|
|
"metadata": {
|
|
"name": "cmthree",
|
|
"namespace": "bar"
|
|
}
|
|
}
|
|
`),
|
|
},
|
|
targetList: "ComfigMapList",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
policy := loadResource[kyverno.ClusterPolicy](t, test.policy)
|
|
trigger := loadUnstructured(t, test.trigger)
|
|
|
|
var targets []runtime.Object
|
|
var patchedTargets []unstructured.Unstructured
|
|
for i := range test.targets {
|
|
target := loadUnstructured(t, test.targets[i])
|
|
targets = append(targets, &target)
|
|
patchedTargets = append(patchedTargets, loadUnstructured(t, test.patchedTargets[i]))
|
|
}
|
|
policyContext := createContext(t, &policy, trigger, kyverno.Create)
|
|
|
|
gvrToListKind := map[schema.GroupVersionResource]string{
|
|
{Group: patchedTargets[0].GroupVersionKind().Group, Version: patchedTargets[0].GroupVersionKind().Version, Resource: patchedTargets[0].GroupVersionKind().Kind}: test.targetList,
|
|
}
|
|
|
|
scheme := runtime.NewScheme()
|
|
dclient, err := client.NewFakeClient(scheme, gvrToListKind, targets...)
|
|
require.NoError(t, err)
|
|
dclient.SetDiscovery(client.NewFakeDiscoveryClient(nil))
|
|
|
|
_, err = dclient.GetResource(context.TODO(), patchedTargets[0].GetAPIVersion(), patchedTargets[0].GetKind(), patchedTargets[0].GetNamespace(), patchedTargets[0].GetName())
|
|
require.NoError(t, err)
|
|
|
|
er := testMutate(context.TODO(), dclient, registryclient.NewOrDie(), policyContext, nil)
|
|
|
|
var actualPatchedTargets []unstructured.Unstructured
|
|
for i := range er.PolicyResponse.Rules {
|
|
rr := er.PolicyResponse.Rules[i]
|
|
require.Equal(t, engineapi.RuleStatusPass, rr.Status())
|
|
p, _, _ := rr.PatchedTarget()
|
|
require.NotNil(t, p)
|
|
actualPatchedTargets = append(actualPatchedTargets, *p)
|
|
}
|
|
require.Equal(t, patchedTargets, actualPatchedTargets)
|
|
}
|
|
}
|
|
|
|
func Test_RuleSelectorMutate(t *testing.T) {
|
|
policyRaw := []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "add-label"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "add-app-label",
|
|
"match": {
|
|
"resources": {
|
|
"name": "check-root-user",
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "root"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "add-appname-label",
|
|
"match": {
|
|
"resources": {
|
|
"kinds": [
|
|
"Pod"
|
|
]
|
|
}
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"appname": "{{request.object.metadata.name}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
resourceRaw := []byte(`{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"name": "check-root-user"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "check-root-user",
|
|
"image": "nginxinc/nginx-unprivileged",
|
|
"securityContext": {
|
|
"runAsNonRoot": true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
var policy kyverno.ClusterPolicy
|
|
err := json.Unmarshal(policyRaw, &policy)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
|
assert.NilError(t, err)
|
|
|
|
policyContext, err := NewPolicyContext(
|
|
jp,
|
|
*resourceUnstructured,
|
|
kyverno.Create,
|
|
nil,
|
|
cfg,
|
|
)
|
|
assert.NilError(t, err)
|
|
policyContext = policyContext.WithPolicy(&policy)
|
|
|
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 2)
|
|
|
|
{
|
|
expectedRaw := []byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "root",
|
|
"appname": "check-root-user"
|
|
},
|
|
"name": "check-root-user"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "nginxinc/nginx-unprivileged",
|
|
"name": "check-root-user",
|
|
"securityContext": {
|
|
"runAsNonRoot": true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
expected := loadUnstructured(t, expectedRaw)
|
|
require.Equal(t, expected, er.PatchedResource)
|
|
}
|
|
|
|
applyOne := kyverno.ApplyOne
|
|
policyContext.Policy().GetSpec().ApplyRules = &applyOne
|
|
|
|
er = testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
|
|
|
{
|
|
expectedRaw := []byte(`
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "Pod",
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "root"
|
|
},
|
|
"name": "check-root-user"
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "nginxinc/nginx-unprivileged",
|
|
"name": "check-root-user",
|
|
"securityContext": {
|
|
"runAsNonRoot": true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`)
|
|
|
|
expected := loadUnstructured(t, expectedRaw)
|
|
require.Equal(t, expected, er.PatchedResource)
|
|
}
|
|
}
|
|
|
|
func Test_SpecialCharacters(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
policyRaw []byte
|
|
documentRaw []byte
|
|
want []string
|
|
}{
|
|
{
|
|
name: "regex_replace",
|
|
policyRaw: []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "regex-replace-all-demo"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "retention-adjust",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Deployment"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"retention": "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`),
|
|
documentRaw: []byte(`{
|
|
"apiVersion": "apps/v1",
|
|
"kind": "Deployment",
|
|
"metadata": {
|
|
"name": "busybox",
|
|
"labels": {
|
|
"app": "busybox",
|
|
"retention": "days_37"
|
|
}
|
|
},
|
|
"spec": {
|
|
"replicas": 3,
|
|
"selector": {
|
|
"matchLabels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "busybox:1.28",
|
|
"name": "busybox",
|
|
"command": [
|
|
"sleep",
|
|
"9999"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}`),
|
|
want: []string{
|
|
`{"op":"replace","path":"/metadata/labels/retention","value":"days_30"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "regex_replace_with_slash",
|
|
policyRaw: []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "regex-replace-all-demo"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "retention-adjust",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Deployment"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"corp.com/retention": "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`),
|
|
documentRaw: []byte(`{
|
|
"apiVersion": "apps/v1",
|
|
"kind": "Deployment",
|
|
"metadata": {
|
|
"name": "busybox",
|
|
"labels": {
|
|
"app": "busybox",
|
|
"corp.com/retention": "days_37"
|
|
}
|
|
},
|
|
"spec": {
|
|
"replicas": 3,
|
|
"selector": {
|
|
"matchLabels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "busybox:1.28",
|
|
"name": "busybox",
|
|
"command": [
|
|
"sleep",
|
|
"9999"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}`),
|
|
want: []string{
|
|
`{"op":"replace","path":"/metadata/labels/corp.com~1retention","value":"days_30"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "regex_replace_with_hyphen",
|
|
policyRaw: []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "regex-replace-all-demo"
|
|
},
|
|
"spec": {
|
|
"background": false,
|
|
"rules": [
|
|
{
|
|
"name": "retention-adjust",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Deployment"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"corp-retention": "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`),
|
|
documentRaw: []byte(`{
|
|
"apiVersion": "apps/v1",
|
|
"kind": "Deployment",
|
|
"metadata": {
|
|
"name": "busybox",
|
|
"labels": {
|
|
"app": "busybox",
|
|
"corp-retention": "days_37"
|
|
}
|
|
},
|
|
"spec": {
|
|
"replicas": 3,
|
|
"selector": {
|
|
"matchLabels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "busybox:1.28",
|
|
"name": "busybox",
|
|
"command": [
|
|
"sleep",
|
|
"9999"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}`),
|
|
want: []string{
|
|
`{"op":"replace","path":"/metadata/labels/corp-retention","value":"days_30"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "to_upper_with_hyphen",
|
|
policyRaw: []byte(`{
|
|
"apiVersion": "kyverno.io/v1",
|
|
"kind": "ClusterPolicy",
|
|
"metadata": {
|
|
"name": "to-upper-demo"
|
|
},
|
|
"spec": {
|
|
"rules": [
|
|
{
|
|
"name": "format-deploy-zone",
|
|
"match": {
|
|
"any": [
|
|
{
|
|
"resources": {
|
|
"kinds": [
|
|
"Deployment"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"mutate": {
|
|
"patchStrategicMerge": {
|
|
"metadata": {
|
|
"labels": {
|
|
"deploy-zone": "{{ to_upper('{{@}}') }}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}`),
|
|
documentRaw: []byte(`{
|
|
"apiVersion": "apps/v1",
|
|
"kind": "Deployment",
|
|
"metadata": {
|
|
"name": "busybox",
|
|
"labels": {
|
|
"app": "busybox",
|
|
"deploy-zone": "eu-central-1"
|
|
}
|
|
},
|
|
"spec": {
|
|
"replicas": 3,
|
|
"selector": {
|
|
"matchLabels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {
|
|
"app": "busybox"
|
|
}
|
|
},
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"image": "busybox:1.28",
|
|
"name": "busybox",
|
|
"command": [
|
|
"sleep",
|
|
"9999"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}`),
|
|
want: []string{
|
|
`{"op":"replace","path":"/metadata/labels/deploy-zone","value":"EU-CENTRAL-1"}`,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Parse policy document.
|
|
var policy kyverno.ClusterPolicy
|
|
if err := json.Unmarshal(tt.policyRaw, &policy); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// Parse resource document.
|
|
resource, err := kubeutils.BytesToUnstructured(tt.documentRaw)
|
|
if err != nil {
|
|
t.Fatalf("ConvertToUnstructured() error = %v", err)
|
|
}
|
|
|
|
// Create policy context.
|
|
policyContext, err := NewPolicyContext(
|
|
jp,
|
|
*resource,
|
|
kyverno.Create,
|
|
nil,
|
|
cfg,
|
|
)
|
|
assert.NilError(t, err)
|
|
policyContext = policyContext.WithPolicy(&policy)
|
|
|
|
// Mutate and make sure that we got the expected amount of rules.
|
|
patches := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil).GetPatches()
|
|
assert.Equal(t, len(patches), len(tt.want))
|
|
for i := range patches {
|
|
assert.Equal(t, patches[i].Json(), tt.want[i])
|
|
}
|
|
})
|
|
}
|
|
}
|