Compare commits
170 Commits
kyverno-pl
...
main
Author | SHA1 | Date |
---|---|---|
|
91863c96c1 | |
|
a2424e5391 | |
|
2f4caa4672 | |
|
ef81703a15 | |
|
0c7b5b46d6 | |
|
340f82c94b | |
|
655dfcf4f5 | |
|
eb351b5840 | |
|
45cac2b7c3 | |
|
b81cc368e4 | |
|
a20824e470 | |
|
80c29972f2 | |
|
46dd341d46 | |
|
5dae0b14f4 | |
|
01aad54097 | |
|
1578367daa | |
|
963287f029 | |
|
9996677e0b | |
|
7ce01062a8 | |
|
b63ce4c8e5 | |
|
ae150269e4 | |
|
63a83e4971 | |
|
89be6a50cf | |
|
59dc54e971 | |
|
a2d4485351 | |
|
12f853cadc | |
|
13d62fe78b | |
|
1d34fe469c | |
|
3af05dc6c8 | |
|
33a43f1f15 | |
|
969e540cf8 | |
|
41e6784302 | |
|
ce56231a17 | |
|
9cc41f1a48 | |
|
87a3cb6dcd | |
|
b8a47d4aa9 | |
|
2ed7d72229 | |
|
8f5d43ccae | |
|
d6c2c7f64d | |
|
e7ed96ceb7 | |
|
53447aec25 | |
|
f67f3d4d29 | |
|
19d213c188 | |
|
7af1fdc7cc | |
|
305d11f459 | |
|
ce125a5d61 | |
|
0d7ad87d2b | |
|
134bff95e7 | |
|
35f01e4262 | |
|
a7d57e8f09 | |
|
046c424ebb | |
|
5675e5e404 | |
|
ad20a75dc3 | |
|
32a7c39ef0 | |
|
efa54fe771 | |
|
fff9484d80 | |
|
8abdc47cae | |
|
df604f6a09 | |
|
0dcb394840 | |
|
53805b645b | |
|
4f7c92d33d | |
|
f87a57f20b | |
|
10fd141b3c | |
|
0eb9ee03c5 | |
|
a97b5e25e6 | |
|
1ca3b3e3ab | |
|
c87978d381 | |
|
4d505d6f5a | |
|
4534b8d8da | |
|
4cc8394b94 | |
|
0b0b0a7e57 | |
|
487615de86 | |
|
cc28e55dc9 | |
|
c72953a516 | |
|
0dbc25d335 | |
|
3dbec86835 | |
|
b6970b9e24 | |
|
d93f254376 | |
|
f11f49d8ee | |
|
876e4c0de4 | |
|
96298b1c93 | |
|
c1fbc86708 | |
|
fb59d03346 | |
|
88287c19cd | |
|
e8a8e14a8e | |
|
321b0c371b | |
|
f03a661a73 | |
|
4b3d9c8c54 | |
|
3c10a5b08b | |
|
63ec0df30b | |
|
0a02ac5732 | |
|
0f028fb532 | |
|
ccdb145e1c | |
|
da45b60235 | |
|
124ea5fa39 | |
|
9a5b01e205 | |
|
fd7e0e51c0 | |
|
19d05cbb04 | |
|
90ee880c78 | |
|
69b7382756 | |
|
3b96ab4a0a | |
|
c8a50f9e21 | |
|
95f531d209 | |
|
a6d1371b65 | |
|
005fbf7f93 | |
|
2c2f76bdf3 | |
|
0a63f12387 | |
|
d64e8e984f | |
|
d173a25597 | |
|
526cb9e3f8 | |
|
b2371793e2 | |
|
ea8d94ef6a | |
|
482957b28d | |
|
b415514bfe | |
|
48a32b9bde | |
|
c4c4e0094c | |
|
eddcb0ae64 | |
|
22b470ef07 | |
|
0976392106 | |
|
ce0ab3a3f9 | |
|
ab466790b6 | |
|
99e16b81be | |
|
5d5766c28d | |
|
6ae9dc2c32 | |
|
13dea7b0c1 | |
|
9ddcb92798 | |
|
6f47f4bc29 | |
|
7ee7ee9c6d | |
|
7c70923e98 | |
|
2bcc002b97 | |
|
bb95d9b899 | |
|
e11d3f3357 | |
|
b41614744b | |
|
5106362b57 | |
|
2f58df34cc | |
|
dab63b7b94 | |
|
70c69689d3 | |
|
80ea5c3380 | |
|
abe212272c | |
|
fac92396e7 | |
|
6ad24b7185 | |
|
eaa911e610 | |
|
c65b9323ed | |
|
a300199c63 | |
|
8cd068fbf6 | |
|
4d079213b7 | |
|
317345e5f8 | |
|
501464849d | |
|
1feb647e20 | |
|
6f6c865111 | |
|
488816a13b | |
|
6f9bc7f936 | |
|
93de4865f9 | |
|
27252fed3c | |
|
430ebb6970 | |
|
e8de40bf5c | |
|
07cc470d6d | |
|
d9b3925801 | |
|
a6ae859a1f | |
|
96e94a8eca | |
|
c7c214a188 | |
|
8e1ac30fdd | |
|
4c17cf1c79 | |
|
5583d235e5 | |
|
43d5c5a50a | |
|
6f1abcd636 | |
|
05a095463c | |
|
ef8f6e3e7d | |
|
d98e8b7847 | |
|
f9237e2dc2 |
|
@ -55,7 +55,7 @@ runs:
|
|||
name: Generate SBOM
|
||||
run: cd ./plugins/${{ inputs.plugin }} && cyclonedx-gomod app -licenses -json -output ../../${{ inputs.sbom-name }}-bom.cdx.json -main .
|
||||
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
||||
with:
|
||||
name: ${{ inputs.sbom-name }}-bom-cdx
|
||||
path: ${{ inputs.sbom-name }}-bom.cdx.json
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: gomod
|
||||
directory: /plugins/kyverno
|
||||
schedule:
|
||||
interval: daily
|
||||
- package-ecosystem: gomod
|
||||
directory: /plugins/trivy
|
||||
schedule:
|
||||
interval: daily
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
|
@ -1,70 +0,0 @@
|
|||
name: Publish Kyverno Plugin OCI Chart
|
||||
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'kyverno-plugin-chart-*'
|
||||
|
||||
jobs:
|
||||
helm-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
|
||||
with:
|
||||
python-version: 3.7
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1
|
||||
|
||||
# - name: Run chart-testing (lint)
|
||||
# run: ct lint --target-branch=main --check-version-increment=false --validate-maintainers=false
|
||||
|
||||
linter-artifacthub:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: artifacthub/ah
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Run ah lint
|
||||
working-directory: ./charts/
|
||||
run: ah lint
|
||||
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: helm-tests
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
|
||||
with:
|
||||
version: v3.10.3
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 # v3.3.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
run: |
|
||||
helm registry login --username ${GITHUB_ACTOR} --password ${{ secrets.GITHUB_TOKEN }} ghcr.io
|
||||
|
||||
- name: Login to Cosign
|
||||
run: |
|
||||
cosign login --username ${GITHUB_ACTOR} --password ${{ secrets.GITHUB_TOKEN }} ghcr.io
|
||||
|
||||
- name: Publish OCI Charts
|
||||
run: |
|
||||
helm package charts/kyverno-plugin --destination .dist
|
||||
helm push .dist/kyverno-plugin-*.tgz oci://ghcr.io/${{ github.repository_owner }}/charts/policy-reporter |& tee .digest
|
||||
cosign sign --yes ghcr.io/${{ github.repository_owner }}/charts/policy-reporter/kyverno-plugin@$(cat .digest | awk -F "[, ]+" '/Digest/{print $NF}')
|
|
@ -20,15 +20,15 @@ jobs:
|
|||
digest: ${{ steps.publish.outputs.digest }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: backend/go.mod
|
||||
cache-dependency-path: backend/go.sum
|
||||
go-version-file: plugins/trivy/go.mod
|
||||
cache-dependency-path: plugins/trivy/go.sum
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca # v0.16.1
|
||||
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4 # v0.32.0
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
ignore-unfixed: true
|
||||
|
@ -37,7 +37,7 @@ jobs:
|
|||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 # v3.3.0
|
||||
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
|
||||
|
||||
- name: Set version
|
||||
run: |
|
||||
|
@ -65,7 +65,7 @@ jobs:
|
|||
packages: write # To upload assets to release.
|
||||
actions: read # To read the workflow path.
|
||||
# NOTE: The container generator workflow is not officially released as GA.
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/policy-reporter/kyverno-plugin
|
||||
digest: "${{ needs.publish-images.outputs.digest }}"
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
name: Publish Trivy Plugin OCI Chart
|
||||
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'trivy-plugin-chart-*'
|
||||
|
||||
jobs:
|
||||
helm-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
|
||||
with:
|
||||
python-version: 3.7
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1
|
||||
|
||||
# - name: Run chart-testing (lint)
|
||||
# run: ct lint --target-branch=main --check-version-increment=false --validate-maintainers=false
|
||||
|
||||
linter-artifacthub:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: artifacthub/ah
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Run ah lint
|
||||
working-directory: ./charts/
|
||||
run: ah lint
|
||||
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: helm-tests
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
|
||||
with:
|
||||
version: v3.10.3
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 # v3.3.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
run: |
|
||||
helm registry login --username ${GITHUB_ACTOR} --password ${{ secrets.GITHUB_TOKEN }} ghcr.io
|
||||
|
||||
- name: Login to Cosign
|
||||
run: |
|
||||
cosign login --username ${GITHUB_ACTOR} --password ${{ secrets.GITHUB_TOKEN }} ghcr.io
|
||||
|
||||
- name: Publish OCI Charts
|
||||
run: |
|
||||
helm package charts/trivy-plugin --destination .dist
|
||||
helm push .dist/trivy-plugin-*.tgz oci://ghcr.io/${{ github.repository_owner }}/charts/policy-reporter |& tee .digest
|
||||
cosign sign --yes ghcr.io/${{ github.repository_owner }}/charts/policy-reporter/trivy-plugin@$(cat .digest | awk -F "[, ]+" '/Digest/{print $NF}')
|
|
@ -20,15 +20,15 @@ jobs:
|
|||
digest: ${{ steps.publish.outputs.digest }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: backend/go.mod
|
||||
cache-dependency-path: backend/go.sum
|
||||
go-version-file: plugins/trivy/go.mod
|
||||
cache-dependency-path: plugins/trivy/go.sum
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca # v0.16.1
|
||||
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4 # v0.32.0
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
ignore-unfixed: true
|
||||
|
@ -37,7 +37,7 @@ jobs:
|
|||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 # v3.3.0
|
||||
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
|
||||
|
||||
- name: Set version
|
||||
run: |
|
||||
|
@ -65,7 +65,7 @@ jobs:
|
|||
packages: write # To upload assets to release.
|
||||
actions: read # To read the workflow path.
|
||||
# NOTE: The container generator workflow is not officially released as GA.
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/policy-reporter/trivy-plugin
|
||||
digest: "${{ needs.publish-images.outputs.digest }}"
|
||||
|
|
32
README.md
32
README.md
|
@ -287,6 +287,38 @@ http://localhost:8083/policies/default/restrict-apparmor-profiles
|
|||
|
||||

|
||||
|
||||
### [POST] V1 Policy Exception API
|
||||
|
||||
The `/v1/policies/exception` API provides a way to create an Exception for a given Resource, Policy and Rules.
|
||||
|
||||
### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"resource": {
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"name": "local-path-provisioner",
|
||||
"namespace": "local-path-storage"
|
||||
},
|
||||
"policies": [{
|
||||
"name": "disallow-capabilities-strict",
|
||||
"rules": ["autogen-require-drop-all"]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"resource": "kind: PolicyException\napiVersion: kyverno.io/v2beta1\nmetadata:\n name: local-path-provisioner-exception\n namespace: local-path-storage\n creationTimestamp: null\nspec:\n match:\n any:\n - resources:\n kinds:\n - Deployment\n - Pod\n - ReplicaSet\n names:\n - local-path-provisioner*\n namespaces:\n - local-path-storage\n exceptions:\n - policyName: disallow-capabilities-strict\n ruleNames:\n - autogen-require-drop-all\n - require-drop-all\n"
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
Examples:
|
||||
## Example Client
|
||||
|
||||
In `/example` you find an example plugin service with fixture content and a Swagger UI.
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
README.md.gotmpl
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: v2
|
||||
name: kyverno-plugin
|
||||
description: Kyverno Plugin for Policy Reporter UI
|
||||
type: application
|
||||
version: 0.0.2
|
||||
appVersion: "0.0.3"
|
|
@ -1,73 +0,0 @@
|
|||
# kyverno-plugin
|
||||
|
||||
Kyverno Plugin for Policy Reporter UI
|
||||
|
||||
  
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find detailed Information and Screens about Features and Configurations in the [Documentation](https://kyverno.github.io/policy-reporter).
|
||||
|
||||
## Values
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| image.registry | string | `"ghcr.io"` | Image registry |
|
||||
| image.repository | string | `"kyverno/policy-reporter/kyverno-plugin"` | Image repository |
|
||||
| image.pullPolicy | string | `"IfNotPresent"` | Image PullPolicy |
|
||||
| image.tag | string | `""` | Image tag Defaults to `Chart.AppVersion` if omitted |
|
||||
| replicaCount | int | `1` | Deployment replica count |
|
||||
| logging.encoding | string | `"console"` | log encoding possible encodings are console and json |
|
||||
| logging.logLevel | int | `0` | log level default info |
|
||||
| server.port | int | `8080` | Application port |
|
||||
| server.logging | bool | `false` | Enables Access logging |
|
||||
| server.basicAuth.username | string | `""` | HTTP BasicAuth username |
|
||||
| server.basicAuth.password | string | `""` | HTTP BasicAuth password |
|
||||
| server.basicAuth.secretRef | string | `""` | Read HTTP BasicAuth credentials from secret |
|
||||
| blockReports.enabled | bool | `false` | Enables he BlockReport feature |
|
||||
| blockReports.eventNamespace | string | `"default"` | Watches for Kyverno Events in the configured namespace leave blank to watch in all namespaces |
|
||||
| blockReports.results.maxPerReport | int | `200` | Max items per PolicyReport resource |
|
||||
| blockReports.results.keepOnlyLatest | bool | `false` | Keep only the latest of duplicated events |
|
||||
| imagePullSecrets | list | `[]` | Image pull secrets for image verification policies, this will define the `--imagePullSecrets` argument |
|
||||
| nameOverride | string | `""` | Override the name of the chart |
|
||||
| fullnameOverride | string | `""` | Override the expanded name of the chart |
|
||||
| serviceAccount.create | bool | `true` | Create ServiceAccount |
|
||||
| serviceAccount.automount | bool | `true` | Enable ServiceAccount automaount |
|
||||
| serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount |
|
||||
| serviceAccount.name | string | `""` | The ServiceAccount name |
|
||||
| podAnnotations | object | `{}` | Additional annotations to add to each pod |
|
||||
| podLabels | object | `{}` | Additional labels to add to each pod |
|
||||
| updateStrategy | object | `{}` | Deployment update strategy. Ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy |
|
||||
| revisionHistoryLimit | int | `10` | The number of revisions to keep |
|
||||
| podSecurityContext | object | `{"runAsGroup":1234,"runAsUser":1234}` | Security context for the pod |
|
||||
| envVars | list | `[]` | Allow additional env variables to be added |
|
||||
| rbac.enabled | bool | `true` | Create RBAC resources |
|
||||
| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsNonRoot":true,"runAsUser":1234,"seccompProfile":{"type":"RuntimeDefault"}}` | Container security context |
|
||||
| service.type | string | `"ClusterIP"` | Service type. |
|
||||
| service.port | int | `8080` | Service port. |
|
||||
| service.annotations | object | `{}` | Service annotations. |
|
||||
| service.labels | object | `{}` | Service labels. |
|
||||
| ingress.enabled | bool | `false` | Create ingress resource. |
|
||||
| ingress.className | string | `""` | Ingress class name. |
|
||||
| ingress.labels | object | `{}` | Ingress labels. |
|
||||
| ingress.annotations | object | `{}` | Ingress annotations. |
|
||||
| ingress.hosts | list | `[]` | List of ingress host configurations. |
|
||||
| ingress.tls | list | `[]` | List of ingress TLS configurations. |
|
||||
| networkPolicy.enabled | bool | `false` | When true, use a NetworkPolicy to allow ingress to the webhook This is useful on clusters using Calico and/or native k8s network policies in a default-deny setup. |
|
||||
| networkPolicy.egress | list | `[{"ports":[{"port":6443,"protocol":"TCP"}]}]` | A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies. Enables Kubernetes API Server by default |
|
||||
| networkPolicy.ingress | list | `[]` | A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies. |
|
||||
| resources | object | `{}` | |
|
||||
| leaderElection.enabled | bool | `false` | Enables LeaderElection. |
|
||||
| leaderElection.lockName | string | `"kyverno-plugin"` | Lock Name |
|
||||
| leaderElection.releaseOnCancel | bool | `true` | Released lock when the run context is cancelled. |
|
||||
| leaderElection.leaseDuration | int | `15` | LeaseDuration is the duration that non-leader candidates will wait to force acquire leadership. |
|
||||
| leaderElection.renewDeadline | int | `10` | RenewDeadline is the duration that the acting master will retry refreshing leadership before giving up. |
|
||||
| leaderElection.retryPeriod | int | `2` | RetryPeriod is the duration the LeaderElector clients should wait between tries of actions. |
|
||||
| podDisruptionBudget.minAvailable | int | `1` | Configures the minimum available pods for kyvernoPlugin disruptions. Cannot be used if `maxUnavailable` is set. |
|
||||
| podDisruptionBudget.maxUnavailable | string | `nil` | Configures the maximum unavailable pods for kyvernoPlugin disruptions. Cannot be used if `minAvailable` is set. |
|
||||
| nodeSelector | object | `{}` | Node labels for pod assignment |
|
||||
| tolerations | list | `[]` | List of node taints to tolerate |
|
||||
| affinity | object | `{}` | Affinity constraints. |
|
||||
|
||||
----------------------------------------------
|
||||
Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0)
|
|
@ -1,19 +0,0 @@
|
|||
{{ template "chart.header" . }}
|
||||
{{ template "chart.deprecationWarning" . }}
|
||||
{{ template "chart.description" . }}
|
||||
|
||||
{{ template "chart.badgesSection" . }}
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find detailed Information and Screens about Features and Configurations in the [Documentation](https://kyverno.github.io/policy-reporter).
|
||||
|
||||
{{ template "chart.valuesSection" . }}
|
||||
|
||||
{{ template "chart.sourcesSection" . }}
|
||||
|
||||
{{ template "chart.requirementsSection" . }}
|
||||
|
||||
{{ template "chart.maintainersSection" . }}
|
||||
|
||||
{{ template "helm-docs.versionFooter" . }}
|
|
@ -1,23 +0,0 @@
|
|||
leaderElection:
|
||||
enabled: {{ or .Values.leaderElection.enabled (gt (int .Values.replicaCount) 1) }}
|
||||
releaseOnCancel: {{ .Values.leaderElection.releaseOnCancel }}
|
||||
leaseDuration: {{ .Values.leaderElection.leaseDuration }}
|
||||
renewDeadline: {{ .Values.leaderElection.renewDeadline }}
|
||||
retryPeriod: {{ .Values.leaderElection.retryPeriod }}
|
||||
lockName: {{ .Values.leaderElection.lockName }}
|
||||
|
||||
logging:
|
||||
encoding: {{ .Values.logging.encoding }}
|
||||
logLevel: {{ .Values.logging.logLevel }}
|
||||
|
||||
server:
|
||||
logging: {{ .Values.server.logging }}
|
||||
basicAuth:
|
||||
username: {{ .Values.server.basicAuth.username }}
|
||||
password: {{ .Values.server.basicAuth.password }}
|
||||
secretRef: {{ .Values.server.basicAuth.secretRef }}
|
||||
|
||||
{{- with .Values.blockReports }}
|
||||
blockReports:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
|
@ -1,22 +0,0 @@
|
|||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "kyverno-plugin.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "kyverno-plugin.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "kyverno-plugin.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "kyverno-plugin.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
|
@ -1,74 +0,0 @@
|
|||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "kyverno-plugin.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "kyverno-plugin.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "kyverno-plugin.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "kyverno-plugin.labels" -}}
|
||||
helm.sh/chart: {{ include "kyverno-plugin.chart" . }}
|
||||
{{ include "kyverno-plugin.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "kyverno-plugin.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "kyverno-plugin.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "kyverno-plugin.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "kyverno-plugin.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kyverno-plugin.podDisruptionBudget" -}}
|
||||
{{- if and .Values.podDisruptionBudget.minAvailable .Values.podDisruptionBudget.maxUnavailable }}
|
||||
{{- fail "Cannot set both .Values.podDisruptionBudget.minAvailable and .Values.podDisruptionBudget.maxUnavailable" -}}
|
||||
{{- end }}
|
||||
{{- if not .Values.podDisruptionBudget.maxUnavailable }}
|
||||
minAvailable: {{ default 1 .Values.podDisruptionBudget.minAvailable }}
|
||||
{{- end }}
|
||||
{{- if .Values.podDisruptionBudget.maxUnavailable }}
|
||||
maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -1,43 +0,0 @@
|
|||
{{- if .Values.rbac.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- '*'
|
||||
resources:
|
||||
- policies
|
||||
- policies/status
|
||||
- clusterpolicies
|
||||
- clusterpolicies/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
{{- if .Values.blockReports.enabled }}
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- '*'
|
||||
resources:
|
||||
- policyreports
|
||||
- policyreports/status
|
||||
- clusterpolicyreports
|
||||
- clusterpolicyreports/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- create
|
||||
- update
|
||||
- delete
|
||||
{{- end }}
|
||||
{{- end -}}
|
|
@ -1,16 +0,0 @@
|
|||
{{- if and .Values.serviceAccount.create .Values.rbac.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: "ServiceAccount"
|
||||
name: {{ include "kyverno-plugin.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end -}}
|
|
@ -1,9 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-config
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
config.yaml: {{ tpl (.Files.Get "config.tmpl") . | b64enc }}
|
|
@ -1,96 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
{{- with .Values.updateStrategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "kyverno-plugin.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/secret: {{ include (print .Template.BasePath "/config-secret.yaml") . | sha256sum | quote }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "kyverno-plugin.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
- run
|
||||
- --config=/app/config.yaml
|
||||
- --port={{ .Values.server.port }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.server.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/policies
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/policies
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config-file
|
||||
mountPath: /app/config.yaml
|
||||
subPath: config.yaml
|
||||
readOnly: true
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- if or .Values.leaderElection.enabled (gt (int .Values.replicaCount) 1) }}
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
{{- end }}
|
||||
{{- with .Values.envVars }}
|
||||
{{- . | toYaml | trim | nindent 10 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config-file
|
||||
secret:
|
||||
secretName: {{ include "kyverno-plugin.fullname" . }}-config
|
||||
optional: true
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
|
@ -1,64 +0,0 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "kyverno-plugin.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -1,21 +0,0 @@
|
|||
{{- if .Values.networkPolicy.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
labels: {{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels: {{- include "kyverno-plugin.selectorLabels" . | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
{{- with .Values.networkPolicy.ingress }}
|
||||
ingress:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.networkPolicy.egress }}
|
||||
egress:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -1,17 +0,0 @@
|
|||
{{- if (gt (int .Values.replicaCount) 1) }}
|
||||
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }}
|
||||
apiVersion: policy/v1
|
||||
{{- else }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- end }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- include "kyverno-plugin.podDisruptionBudget" . | indent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "kyverno-plugin.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
|
@ -1,19 +0,0 @@
|
|||
{{- if and (and .Values.serviceAccount.create .Values.rbac.enabled) (and .Values.blockReports.enabled (or .Values.leaderElection.enabled (gt (int .Values.replicaCount) 1))) -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-leaderelection
|
||||
rules:
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- leases
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
{{- end -}}
|
|
@ -1,16 +0,0 @@
|
|||
{{- if and (and .Values.serviceAccount.create .Values.rbac.enabled) (and .Values.blockReports.enabled (or .Values.leaderElection.enabled (gt (int .Values.replicaCount) 1))) -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-leaderelection
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-leaderelection
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: "ServiceAccount"
|
||||
name: {{ include "kyverno-plugin.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end -}}
|
|
@ -1,14 +0,0 @@
|
|||
{{- if and .Values.serviceAccount.create .Values.rbac.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-secret-reader
|
||||
rules:
|
||||
- apiGroups: ['']
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
{{- end -}}
|
|
@ -1,16 +0,0 @@
|
|||
{{- if and .Values.serviceAccount.create .Values.rbac.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-secret-reader
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "kyverno-plugin.fullname" . }}-secret-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: "ServiceAccount"
|
||||
name: {{ include "kyverno-plugin.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end -}}
|
|
@ -1,22 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "kyverno-plugin.selectorLabels" . | nindent 4 }}
|
|
@ -1,13 +0,0 @@
|
|||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "kyverno-plugin.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "kyverno-plugin.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
|
@ -1,203 +0,0 @@
|
|||
image:
|
||||
# -- (string) Image registry
|
||||
registry: ghcr.io
|
||||
# -- (string) Image repository
|
||||
repository: kyverno/policy-reporter/kyverno-plugin
|
||||
# -- (string) Image PullPolicy
|
||||
pullPolicy: IfNotPresent
|
||||
# -- (string) Image tag
|
||||
# Defaults to `Chart.AppVersion` if omitted
|
||||
tag: ""
|
||||
|
||||
# -- Deployment replica count
|
||||
replicaCount: 1
|
||||
|
||||
logging:
|
||||
# -- log encoding
|
||||
# possible encodings are console and json
|
||||
encoding: console
|
||||
# -- log level
|
||||
# default info
|
||||
logLevel: 0
|
||||
|
||||
server:
|
||||
# -- Application port
|
||||
port: 8080
|
||||
# -- Enables Access logging
|
||||
logging: false
|
||||
basicAuth:
|
||||
# -- HTTP BasicAuth username
|
||||
username: ""
|
||||
# -- HTTP BasicAuth password
|
||||
password: ""
|
||||
# -- Read HTTP BasicAuth credentials from secret
|
||||
secretRef: ""
|
||||
|
||||
blockReports:
|
||||
# -- Enables he BlockReport feature
|
||||
enabled: false
|
||||
# -- Watches for Kyverno Events in the configured namespace
|
||||
# leave blank to watch in all namespaces
|
||||
eventNamespace: default
|
||||
results:
|
||||
# -- Max items per PolicyReport resource
|
||||
maxPerReport: 200
|
||||
# -- Keep only the latest of duplicated events
|
||||
keepOnlyLatest: false
|
||||
|
||||
# -- Image pull secrets for image verification policies, this will define the `--imagePullSecrets` argument
|
||||
imagePullSecrets: []
|
||||
# regcred:
|
||||
# registry: foo.example.com
|
||||
# username: foobar
|
||||
# password: secret
|
||||
|
||||
# -- (string) Override the name of the chart
|
||||
nameOverride: ""
|
||||
# -- (string) Override the expanded name of the chart
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# -- Create ServiceAccount
|
||||
create: true
|
||||
# -- Enable ServiceAccount automaount
|
||||
automount: true
|
||||
# -- Annotations for the ServiceAccount
|
||||
annotations: {}
|
||||
# -- The ServiceAccount name
|
||||
name: ""
|
||||
|
||||
# -- Additional annotations to add to each pod
|
||||
podAnnotations: {}
|
||||
|
||||
# -- Additional labels to add to each pod
|
||||
podLabels: {}
|
||||
|
||||
# -- Deployment update strategy.
|
||||
# Ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
|
||||
updateStrategy: {}
|
||||
# rollingUpdate:
|
||||
# maxSurge: 1
|
||||
# maxUnavailable: 40%
|
||||
# type: RollingUpdate
|
||||
|
||||
# -- The number of revisions to keep
|
||||
revisionHistoryLimit: 10
|
||||
|
||||
# -- Security context for the pod
|
||||
podSecurityContext:
|
||||
runAsUser: 1234
|
||||
runAsGroup: 1234
|
||||
|
||||
# -- Allow additional env variables to be added
|
||||
envVars: []
|
||||
|
||||
rbac:
|
||||
# -- Create RBAC resources
|
||||
enabled: true
|
||||
|
||||
# -- Container security context
|
||||
securityContext:
|
||||
runAsUser: 1234
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
service:
|
||||
# -- Service type.
|
||||
type: ClusterIP
|
||||
# -- Service port.
|
||||
port: 8080
|
||||
# -- Service annotations.
|
||||
annotations: {}
|
||||
# -- Service labels.
|
||||
labels: {}
|
||||
|
||||
ingress:
|
||||
# -- Create ingress resource.
|
||||
enabled: false
|
||||
# -- Ingress class name.
|
||||
className: ""
|
||||
# -- Ingress labels.
|
||||
labels: {}
|
||||
# -- Ingress annotations.
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
# -- List of ingress host configurations.
|
||||
hosts: []
|
||||
# - host: chart-example.local
|
||||
# paths:
|
||||
# - path: /
|
||||
# pathType: ImplementationSpecific
|
||||
# -- List of ingress TLS configurations.
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
networkPolicy:
|
||||
# -- When true, use a NetworkPolicy to allow ingress to the webhook
|
||||
# This is useful on clusters using Calico and/or native k8s network policies in a default-deny setup.
|
||||
enabled: false
|
||||
# -- A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies.
|
||||
# Enables Kubernetes API Server by default
|
||||
egress:
|
||||
- ports:
|
||||
- protocol: TCP
|
||||
port: 6443
|
||||
# -- A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies.
|
||||
ingress: []
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
# required for HA mode
|
||||
# if "blockReports" is disabled, leaderElection is also disabled automatically
|
||||
# will be enabled when replicaCount > 1
|
||||
leaderElection:
|
||||
# -- Enables LeaderElection.
|
||||
enabled: false
|
||||
# -- Lock Name
|
||||
lockName: kyverno-plugin
|
||||
# -- Released lock when the run context is cancelled.
|
||||
releaseOnCancel: true
|
||||
# -- LeaseDuration is the duration that non-leader candidates will wait to force acquire leadership.
|
||||
leaseDuration: 15
|
||||
# -- RenewDeadline is the duration that the acting master will retry refreshing leadership before giving up.
|
||||
renewDeadline: 10
|
||||
# -- RetryPeriod is the duration the LeaderElector clients should wait between tries of actions.
|
||||
retryPeriod: 2
|
||||
|
||||
# enabled if replicaCount > 1
|
||||
podDisruptionBudget:
|
||||
# -- Configures the minimum available pods for kyvernoPlugin disruptions.
|
||||
# Cannot be used if `maxUnavailable` is set.
|
||||
minAvailable: 1
|
||||
# -- Configures the maximum unavailable pods for kyvernoPlugin disruptions.
|
||||
# Cannot be used if `minAvailable` is set.
|
||||
maxUnavailable:
|
||||
|
||||
# -- Node labels for pod assignment
|
||||
nodeSelector: {}
|
||||
|
||||
# -- List of node taints to tolerate
|
||||
tolerations: []
|
||||
|
||||
# -- Affinity constraints.
|
||||
affinity: {}
|
|
@ -1,24 +0,0 @@
|
|||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
README.md.gotmpl
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: v2
|
||||
name: trivy-plugin
|
||||
description: Trivy Plugin for Policy Reporter UI
|
||||
type: application
|
||||
version: 0.0.4
|
||||
appVersion: "0.0.3"
|
|
@ -1,69 +0,0 @@
|
|||
# trivy-plugin
|
||||
|
||||
Trivy Plugin for Policy Reporter UI
|
||||
|
||||
  
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find detailed Information and Screens about Features and Configurations in the [Documentation](https://kyverno.github.io/policy-reporter).
|
||||
|
||||
## Values
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| image.registry | string | `"ghcr.io"` | Image registry |
|
||||
| image.repository | string | `"kyverno/policy-reporter/trivy-plugin"` | Image repository |
|
||||
| image.pullPolicy | string | `"IfNotPresent"` | Image PullPolicy |
|
||||
| image.tag | string | `""` | Image tag Defaults to `Chart.AppVersion` if omitted |
|
||||
| replicaCount | int | `1` | Deployment replica count |
|
||||
| logging.encoding | string | `"console"` | log encoding possible encodings are console and json |
|
||||
| logging.logLevel | int | `0` | log level default info |
|
||||
| server.port | int | `8080` | Application port |
|
||||
| server.logging | bool | `false` | Enables Access logging |
|
||||
| server.basicAuth.username | string | `""` | HTTP BasicAuth username |
|
||||
| server.basicAuth.password | string | `""` | HTTP BasicAuth password |
|
||||
| server.basicAuth.secretRef | string | `""` | Read HTTP BasicAuth credentials from secret |
|
||||
| policyReporter.host | string | `""` | Host of the Policy Reporter Core App |
|
||||
| policyReporter.skipTLS | bool | `false` | Skip TLS Verification |
|
||||
| policyReporter.certificate | string | `""` | TLS Certificate |
|
||||
| policyReporter.basicAuth.username | string | `""` | HTTP BasicAuth Username |
|
||||
| policyReporter.basicAuth.password | string | `""` | HTTP BasicAuth Password |
|
||||
| policyReporter.secretRef | string | `""` | Secret to read the API configuration from supports `host`, `certificate`, `skipTLS`, `username`, `password` key |
|
||||
| imagePullSecrets | list | `[]` | Image pull secrets for image verification policies, this will define the `--imagePullSecrets` argument |
|
||||
| nameOverride | string | `""` | Override the name of the chart |
|
||||
| fullnameOverride | string | `""` | Override the expanded name of the chart |
|
||||
| serviceAccount.create | bool | `true` | Create ServiceAccount |
|
||||
| serviceAccount.automount | bool | `true` | Enable ServiceAccount automaount |
|
||||
| serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount |
|
||||
| serviceAccount.name | string | `""` | The ServiceAccount name |
|
||||
| podAnnotations | object | `{}` | Additional annotations to add to each pod |
|
||||
| podLabels | object | `{}` | Additional labels to add to each pod |
|
||||
| updateStrategy | object | `{}` | Deployment update strategy. Ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy |
|
||||
| revisionHistoryLimit | int | `10` | The number of revisions to keep |
|
||||
| podSecurityContext | object | `{"runAsGroup":1234,"runAsUser":1234}` | Security context for the pod |
|
||||
| envVars | list | `[]` | Allow additional env variables to be added |
|
||||
| rbac.enabled | bool | `true` | Create RBAC resources |
|
||||
| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsNonRoot":true,"runAsUser":1234,"seccompProfile":{"type":"RuntimeDefault"}}` | Container security context |
|
||||
| service.type | string | `"ClusterIP"` | Service type. |
|
||||
| service.port | int | `8080` | Service port. |
|
||||
| service.annotations | object | `{}` | Service annotations. |
|
||||
| service.labels | object | `{}` | Service labels. |
|
||||
| ingress.enabled | bool | `false` | Create ingress resource. |
|
||||
| ingress.className | string | `""` | Ingress class name. |
|
||||
| ingress.labels | object | `{}` | Ingress labels. |
|
||||
| ingress.annotations | object | `{}` | Ingress annotations. |
|
||||
| ingress.hosts | list | `[]` | List of ingress host configurations. |
|
||||
| ingress.tls | list | `[]` | List of ingress TLS configurations. |
|
||||
| networkPolicy.enabled | bool | `false` | When true, use a NetworkPolicy to allow ingress to the webhook This is useful on clusters using Calico and/or native k8s network policies in a default-deny setup. |
|
||||
| networkPolicy.egress | list | `[{"ports":[{"port":6443,"protocol":"TCP"}]}]` | A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies. Enables Kubernetes API Server by default |
|
||||
| networkPolicy.ingress | list | `[]` | A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies. |
|
||||
| resources | object | `{}` | |
|
||||
| podDisruptionBudget.minAvailable | int | `1` | Configures the minimum available pods for kyvernoPlugin disruptions. Cannot be used if `maxUnavailable` is set. |
|
||||
| podDisruptionBudget.maxUnavailable | string | `nil` | Configures the maximum unavailable pods for kyvernoPlugin disruptions. Cannot be used if `minAvailable` is set. |
|
||||
| nodeSelector | object | `{}` | Node labels for pod assignment |
|
||||
| tolerations | list | `[]` | List of node taints to tolerate |
|
||||
| affinity | object | `{}` | Affinity constraints. |
|
||||
|
||||
----------------------------------------------
|
||||
Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0)
|
|
@ -1,19 +0,0 @@
|
|||
{{ template "chart.header" . }}
|
||||
{{ template "chart.deprecationWarning" . }}
|
||||
{{ template "chart.description" . }}
|
||||
|
||||
{{ template "chart.badgesSection" . }}
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find detailed Information and Screens about Features and Configurations in the [Documentation](https://kyverno.github.io/policy-reporter).
|
||||
|
||||
{{ template "chart.valuesSection" . }}
|
||||
|
||||
{{ template "chart.sourcesSection" . }}
|
||||
|
||||
{{ template "chart.requirementsSection" . }}
|
||||
|
||||
{{ template "chart.maintainersSection" . }}
|
||||
|
||||
{{ template "helm-docs.versionFooter" . }}
|
|
@ -1,20 +0,0 @@
|
|||
logging:
|
||||
encoding: {{ .Values.logging.encoding }}
|
||||
logLevel: {{ .Values.logging.logLevel }}
|
||||
|
||||
server:
|
||||
logging: {{ .Values.server.logging }}
|
||||
basicAuth:
|
||||
username: {{ .Values.server.basicAuth.username }}
|
||||
password: {{ .Values.server.basicAuth.password }}
|
||||
secretRef: {{ .Values.server.basicAuth.secretRef }}
|
||||
|
||||
core:
|
||||
host: {{ tpl .Values.policyReporter.host . }}
|
||||
skipTLS: {{ .Values.policyReporter.skipTLS }}
|
||||
certificate: {{ .Values.policyReporter.certificate }}
|
||||
secretRef: {{ .Values.policyReporter.secretRef }}
|
||||
basicAuth:
|
||||
username: {{ .Values.policyReporter.basicAuth.username }}
|
||||
password: {{ .Values.policyReporter.basicAuth.password }}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "trivy-plugin.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "trivy-plugin.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "trivy-plugin.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "trivy-plugin.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
|
@ -1,74 +0,0 @@
|
|||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "trivy-plugin.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "trivy-plugin.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "trivy-plugin.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "trivy-plugin.labels" -}}
|
||||
helm.sh/chart: {{ include "trivy-plugin.chart" . }}
|
||||
{{ include "trivy-plugin.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "trivy-plugin.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "trivy-plugin.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "trivy-plugin.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "trivy-plugin.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "trivy-plugin.podDisruptionBudget" -}}
|
||||
{{- if and .Values.podDisruptionBudget.minAvailable .Values.podDisruptionBudget.maxUnavailable }}
|
||||
{{- fail "Cannot set both .Values.podDisruptionBudget.minAvailable and .Values.podDisruptionBudget.maxUnavailable" -}}
|
||||
{{- end }}
|
||||
{{- if not .Values.podDisruptionBudget.maxUnavailable }}
|
||||
minAvailable: {{ default 1 .Values.podDisruptionBudget.minAvailable }}
|
||||
{{- end }}
|
||||
{{- if .Values.podDisruptionBudget.maxUnavailable }}
|
||||
maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -1,9 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "trivy-plugin.fullname" . }}-config
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
config.yaml: {{ tpl (.Files.Get "config.tmpl") . | b64enc }}
|
|
@ -1,90 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "trivy-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
{{- with .Values.updateStrategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trivy-plugin.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/secret: {{ include (print .Template.BasePath "/config-secret.yaml") . | sha256sum | quote }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "trivy-plugin.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
- run
|
||||
- --config=/app/config.yaml
|
||||
- --port={{ .Values.server.port }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.server.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/vulnr/policies
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/vulnr/policies
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config-file
|
||||
mountPath: /app/config.yaml
|
||||
subPath: config.yaml
|
||||
readOnly: true
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- with .Values.envVars }}
|
||||
{{- . | toYaml | trim | nindent 10 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config-file
|
||||
secret:
|
||||
secretName: {{ include "trivy-plugin.fullname" . }}-config
|
||||
optional: true
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
|
@ -1,64 +0,0 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "trivy-plugin.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -1,21 +0,0 @@
|
|||
{{- if .Values.networkPolicy.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
labels: {{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
name: {{ include "trivy-plugin.fullname" . }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels: {{- include "trivy-plugin.selectorLabels" . | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
{{- with .Values.networkPolicy.ingress }}
|
||||
ingress:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.networkPolicy.egress }}
|
||||
egress:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -1,17 +0,0 @@
|
|||
{{- if (gt (int .Values.replicaCount) 1) }}
|
||||
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }}
|
||||
apiVersion: policy/v1
|
||||
{{- else }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- end }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "trivy-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- include "trivy-plugin.podDisruptionBudget" . | indent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trivy-plugin.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
|
@ -1,14 +0,0 @@
|
|||
{{- if and .Values.serviceAccount.create .Values.rbac.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
name: {{ include "trivy-plugin.fullname" . }}-secret-reader
|
||||
rules:
|
||||
- apiGroups: ['']
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
{{- end -}}
|
|
@ -1,16 +0,0 @@
|
|||
{{- if and .Values.serviceAccount.create .Values.rbac.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "trivy-plugin.fullname" . }}-secret-reader
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "trivy-plugin.fullname" . }}-secret-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: "ServiceAccount"
|
||||
name: {{ include "trivy-plugin.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end -}}
|
|
@ -1,22 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "trivy-plugin.fullname" . }}
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "trivy-plugin.selectorLabels" . | nindent 4 }}
|
|
@ -1,13 +0,0 @@
|
|||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "trivy-plugin.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "trivy-plugin.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
|
@ -1,190 +0,0 @@
|
|||
image:
|
||||
# -- (string) Image registry
|
||||
registry: ghcr.io
|
||||
# -- (string) Image repository
|
||||
repository: kyverno/policy-reporter/trivy-plugin
|
||||
# -- (string) Image PullPolicy
|
||||
pullPolicy: IfNotPresent
|
||||
# -- (string) Image tag
|
||||
# Defaults to `Chart.AppVersion` if omitted
|
||||
tag: ""
|
||||
|
||||
# -- Deployment replica count
|
||||
replicaCount: 1
|
||||
|
||||
logging:
|
||||
# -- log encoding
|
||||
# possible encodings are console and json
|
||||
encoding: console
|
||||
# -- log level
|
||||
# default info
|
||||
logLevel: 0
|
||||
|
||||
server:
|
||||
# -- Application port
|
||||
port: 8080
|
||||
# -- Enables Access logging
|
||||
logging: false
|
||||
basicAuth:
|
||||
# -- HTTP BasicAuth username
|
||||
username: ""
|
||||
# -- HTTP BasicAuth password
|
||||
password: ""
|
||||
# -- Read HTTP BasicAuth credentials from secret
|
||||
secretRef: ""
|
||||
|
||||
policyReporter:
|
||||
# -- Host of the Policy Reporter Core App
|
||||
host: "http://policy-reporter:8080"
|
||||
# -- Skip TLS Verification
|
||||
skipTLS: false
|
||||
# -- TLS Certificate
|
||||
certificate: ""
|
||||
basicAuth:
|
||||
# -- HTTP BasicAuth Username
|
||||
username: ""
|
||||
# -- HTTP BasicAuth Password
|
||||
password: ""
|
||||
# -- Secret to read the API configuration from
|
||||
# supports `host`, `certificate`, `skipTLS`, `username`, `password` key
|
||||
secretRef: ""
|
||||
|
||||
# -- Image pull secrets for image verification policies, this will define the `--imagePullSecrets` argument
|
||||
imagePullSecrets: []
|
||||
# regcred:
|
||||
# registry: foo.example.com
|
||||
# username: foobar
|
||||
# password: secret
|
||||
|
||||
# -- (string) Override the name of the chart
|
||||
nameOverride: ""
|
||||
# -- (string) Override the expanded name of the chart
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# -- Create ServiceAccount
|
||||
create: true
|
||||
# -- Enable ServiceAccount automaount
|
||||
automount: true
|
||||
# -- Annotations for the ServiceAccount
|
||||
annotations: {}
|
||||
# -- The ServiceAccount name
|
||||
name: ""
|
||||
|
||||
# -- Additional annotations to add to each pod
|
||||
podAnnotations: {}
|
||||
|
||||
# -- Additional labels to add to each pod
|
||||
podLabels: {}
|
||||
|
||||
# -- Deployment update strategy.
|
||||
# Ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
|
||||
updateStrategy: {}
|
||||
# rollingUpdate:
|
||||
# maxSurge: 1
|
||||
# maxUnavailable: 40%
|
||||
# type: RollingUpdate
|
||||
|
||||
# -- The number of revisions to keep
|
||||
revisionHistoryLimit: 10
|
||||
|
||||
# -- Security context for the pod
|
||||
podSecurityContext:
|
||||
runAsUser: 1234
|
||||
runAsGroup: 1234
|
||||
|
||||
# -- Allow additional env variables to be added
|
||||
envVars: []
|
||||
|
||||
rbac:
|
||||
# -- Create RBAC resources
|
||||
enabled: true
|
||||
|
||||
# -- Container security context
|
||||
securityContext:
|
||||
runAsUser: 1234
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
service:
|
||||
# -- Service type.
|
||||
type: ClusterIP
|
||||
# -- Service port.
|
||||
port: 8080
|
||||
# -- Service annotations.
|
||||
annotations: {}
|
||||
# -- Service labels.
|
||||
labels: {}
|
||||
|
||||
ingress:
|
||||
# -- Create ingress resource.
|
||||
enabled: false
|
||||
# -- Ingress class name.
|
||||
className: ""
|
||||
# -- Ingress labels.
|
||||
labels: {}
|
||||
# -- Ingress annotations.
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
# -- List of ingress host configurations.
|
||||
hosts: []
|
||||
# - host: chart-example.local
|
||||
# paths:
|
||||
# - path: /
|
||||
# pathType: ImplementationSpecific
|
||||
# -- List of ingress TLS configurations.
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
networkPolicy:
|
||||
# -- When true, use a NetworkPolicy to allow ingress to the webhook
|
||||
# This is useful on clusters using Calico and/or native k8s network policies in a default-deny setup.
|
||||
enabled: false
|
||||
# -- A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies.
|
||||
# Enables Kubernetes API Server by default
|
||||
egress:
|
||||
- ports:
|
||||
- protocol: TCP
|
||||
port: 6443
|
||||
# -- A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies.
|
||||
ingress: []
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
# enabled if replicaCount > 1
|
||||
podDisruptionBudget:
|
||||
# -- Configures the minimum available pods for kyvernoPlugin disruptions.
|
||||
# Cannot be used if `maxUnavailable` is set.
|
||||
minAvailable: 1
|
||||
# -- Configures the maximum unavailable pods for kyvernoPlugin disruptions.
|
||||
# Cannot be used if `minAvailable` is set.
|
||||
maxUnavailable:
|
||||
|
||||
# -- Node labels for pod assignment
|
||||
nodeSelector: {}
|
||||
|
||||
# -- List of node taints to tolerate
|
||||
tolerations: []
|
||||
|
||||
# -- Affinity constraints.
|
||||
affinity: {}
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#########
|
||||
# TOOLS #
|
||||
#########
|
||||
|
||||
TOOLS_DIR ?= $(PWD)/.tools
|
||||
CONTROLLER_GEN := $(TOOLS_DIR)/controller-gen
|
||||
CONTROLLER_GEN_VERSION ?= v0.17.3
|
||||
CLIENT_GEN ?= $(TOOLS_DIR)/client-gen
|
||||
CODE_GEN_VERSION ?= v0.32.4
|
||||
REGISTER_GEN ?= $(TOOLS_DIR)/register-gen
|
||||
DEEPCOPY_GEN ?= $(TOOLS_DIR)/deepcopy-gen
|
||||
|
||||
###########
|
||||
# CODEGEN #
|
||||
###########
|
||||
|
||||
PACKAGE := github.com/kyverno/policy-reporter/kyverno-plugin
|
||||
CLIENT_PACKAGE := $(PACKAGE)/pkg/crd/client
|
||||
CLIENTSET_PACKAGE := $(CLIENT_PACKAGE)/clientset
|
||||
|
||||
$(CLIENT_GEN):
|
||||
@echo Install client-gen... >&2
|
||||
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/client-gen@$(CODE_GEN_VERSION)
|
||||
|
||||
$(REGISTER_GEN):
|
||||
@echo Install register-gen... >&2
|
||||
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/register-gen@$(CODE_GEN_VERSION)
|
||||
|
||||
$(DEEPCOPY_GEN):
|
||||
@echo Install deepcopy-gen... >&2
|
||||
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/deepcopy-gen@$(CODE_GEN_VERSION)
|
||||
|
||||
.PHONY: codegen-api-register
|
||||
codegen-api-register: ## Generate API types registrations
|
||||
codegen-api-register: $(REGISTER_GEN)
|
||||
@echo Generate registration... >&2
|
||||
@$(REGISTER_GEN) --go-header-file=./scripts/boilerplate.go.txt --output-file zz_generated.register.go ./pkg/crd/api/...
|
||||
|
||||
.PHONY: codegen-api-deepcopy
|
||||
codegen-api-deepcopy: ## Generate API deep copy functions
|
||||
codegen-api-deepcopy: $(DEEPCOPY_GEN)
|
||||
@echo Generate deep copy functions... >&2
|
||||
@$(DEEPCOPY_GEN) --go-header-file ./scripts/boilerplate.go.txt --output-file zz_generated.deepcopy.go ./pkg/crd/api/...
|
||||
|
||||
.PHONY: codegen-client-clientset
|
||||
codegen-client-clientset: ## Generate clientset
|
||||
codegen-client-clientset: $(CLIENT_GEN)
|
||||
@echo Generate clientset... >&2
|
||||
@rm -rf ./pkg/crd/client/clientset && mkdir -p ./pkg/crd/client/clientset
|
||||
@$(CLIENT_GEN) \
|
||||
--go-header-file ./scripts/boilerplate.go.txt \
|
||||
--clientset-name versioned \
|
||||
--output-dir ./pkg/crd/client/clientset \
|
||||
--output-pkg $(CLIENTSET_PACKAGE) \
|
||||
--input-base github.com/kyverno/policy-reporter/kyverno-plugin \
|
||||
--input ./pkg/crd/api/kyverno/v1 \
|
||||
--input ./pkg/crd/api/kyverno/v2beta1 \
|
||||
--input ./pkg/crd/api/policyreport/v1alpha2 \
|
||||
--input ./pkg/crd/api/policies.kyverno.io/v1alpha1
|
|
@ -6,12 +6,15 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/config"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/server"
|
||||
v1 "github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/server/v1"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/violation"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/config"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/server"
|
||||
ivpolv1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/server/ivpol/v1"
|
||||
polv1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/server/v1"
|
||||
vpolv1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/server/vpol/v1"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/violation"
|
||||
)
|
||||
|
||||
var configFile string
|
||||
|
@ -36,19 +39,33 @@ func newRunCMD() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
vpols, err := resolver.VPOLClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ivpols, err := resolver.IVPOLClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
coreAPI, err := resolver.CoreClient(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
server, err := resolver.Server(cmd.Context(), []server.ServerOption{
|
||||
v1.WithAPI(client, coreAPI),
|
||||
polv1.WithAPI(client, coreAPI),
|
||||
vpolv1.WithAPI(vpols, coreAPI),
|
||||
ivpolv1.WithAPI(ivpols, coreAPI),
|
||||
server.WithPort(c.Server.Port),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
group := &errgroup.Group{}
|
||||
|
||||
if c.BlockReports.Enabled {
|
||||
logger.Info("block reports enabled", zap.Int("resultsPerReport", c.BlockReports.Results.MaxPerReport))
|
||||
eventClient, err := resolver.EventClient()
|
||||
|
@ -77,9 +94,20 @@ func newRunCMD() *cobra.Command {
|
|||
leClient.RegisterOnStart(func(c context.Context) {
|
||||
logger.Info("started leadership")
|
||||
|
||||
stop = make(chan struct{})
|
||||
g := &errgroup.Group{}
|
||||
g.Go(func() error {
|
||||
return policyReportClient.UpdatePolicyReports(c)
|
||||
})
|
||||
g.Go(func() error {
|
||||
return policyReportClient.UpdateClusterPolicyReports(c)
|
||||
})
|
||||
|
||||
if err = eventClient.Run(c, stop); err != nil {
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error("failed to update existing policy reports", zap.Error(err))
|
||||
}
|
||||
|
||||
stop = make(chan struct{})
|
||||
if err := eventClient.Run(c, stop); err != nil {
|
||||
logger.Error("failed to run EventClient", zap.Error(err))
|
||||
}
|
||||
}).RegisterOnNew(func(currentID, lockID string) {
|
||||
|
@ -91,17 +119,35 @@ func newRunCMD() *cobra.Command {
|
|||
close(stop)
|
||||
})
|
||||
|
||||
go leClient.Run(cmd.Context())
|
||||
group.Go(func() error {
|
||||
leClient.Run(cmd.Context())
|
||||
return nil
|
||||
})
|
||||
} else {
|
||||
stop = make(chan struct{})
|
||||
if err = eventClient.Run(cmd.Context(), stop); err != nil {
|
||||
return err
|
||||
}
|
||||
group.Go(func() error {
|
||||
g := &errgroup.Group{}
|
||||
g.Go(func() error {
|
||||
return policyReportClient.UpdatePolicyReports(cmd.Context())
|
||||
})
|
||||
g.Go(func() error {
|
||||
return policyReportClient.UpdateClusterPolicyReports(cmd.Context())
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error("failed to update existing policy reports", zap.Error(err))
|
||||
}
|
||||
|
||||
return eventClient.Run(cmd.Context(), stop)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("server starts", zap.Int("port", c.Server.Port))
|
||||
return server.Start()
|
||||
group.Go(func() error {
|
||||
logger.Info("server starts", zap.Int("port", c.Server.Port))
|
||||
return server.Start()
|
||||
})
|
||||
|
||||
return group.Wait()
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -26,5 +26,5 @@ helm repo update
|
|||
Install the Policy Reporter Preview
|
||||
|
||||
```bash
|
||||
helm upgrade --install policy-reporter policy-reporter/policy-reporter-preview --create-namespace -n policy-reporter --devel --set ui.enabled=true --set kyverno-plugin.enabled=true
|
||||
helm upgrade --install policy-reporter policy-reporter/policy-reporter-preview --create-namespace -n policy-reporter --devel --set ui.enabled=true --set plugin.kyverno.enabled=true
|
||||
```
|
||||
|
|
|
@ -1,98 +1,279 @@
|
|||
module github.com/kyverno/policy-reporter-plugins/plugins/kyverno
|
||||
module github.com/kyverno/policy-reporter/kyverno-plugin
|
||||
|
||||
go 1.21.3
|
||||
go 1.24.4
|
||||
|
||||
replace github.com/kyverno/policy-reporter-plugins/sdk/api v0.0.0 => ../../sdk/api
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-contrib/pprof v1.4.0
|
||||
github.com/gin-contrib/zap v0.2.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/gin-contrib/gzip v1.2.3
|
||||
github.com/gin-contrib/pprof v1.5.3
|
||||
github.com/gin-contrib/zap v1.1.5
|
||||
github.com/gin-gonic/gin v1.10.1
|
||||
github.com/itchyny/json2yaml v0.1.4
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/kyverno/kyverno-json v0.0.4-0.20240730143747-aade3d42fc0e
|
||||
github.com/kyverno/policy-reporter-plugins/sdk/api v0.0.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/segmentio/fasthash v1.0.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/viper v1.18.2
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/net v0.20.0
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/text v0.14.0
|
||||
github.com/sigstore/k8s-manifest-sigstore v0.5.4
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/viper v1.20.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/net v0.41.0
|
||||
golang.org/x/sync v0.16.0
|
||||
golang.org/x/text v0.27.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
k8s.io/api v0.29.1
|
||||
k8s.io/apiextensions-apiserver v0.29.1
|
||||
k8s.io/apimachinery v0.29.1
|
||||
k8s.io/client-go v0.29.1
|
||||
k8s.io/pod-security-admission v0.29.1
|
||||
k8s.io/api v0.33.2
|
||||
k8s.io/apiextensions-apiserver v0.33.2
|
||||
k8s.io/apimachinery v0.33.2
|
||||
k8s.io/client-go v0.33.2
|
||||
k8s.io/pod-security-admission v0.33.2
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.10.2 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||
cloud.google.com/go/auth v0.16.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20250530080122-d0efc28a5723 // indirect
|
||||
cuelang.org/go v0.13.2 // indirect
|
||||
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.18.1 // indirect
|
||||
github.com/AliyunContainerService/ack-ram-tool/pkg/ecsmetadata v0.0.9 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.30 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.24 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.7 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.1 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.2 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/ThalesIgnite/crypto11 v1.2.5 // indirect
|
||||
github.com/agnivade/levenshtein v1.2.1 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect
|
||||
github.com/alibabacloud-go/cr-20181201 v1.0.10 // indirect
|
||||
github.com/alibabacloud-go/darabonba-openapi v0.2.1 // indirect
|
||||
github.com/alibabacloud-go/debug v1.0.1 // indirect
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect
|
||||
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
|
||||
github.com/alibabacloud-go/tea v1.3.9 // indirect
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
|
||||
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
|
||||
github.com/aliyun/credentials-go v1.4.6 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.45.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect
|
||||
github.com/aws/smithy-go v1.22.4 // indirect
|
||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.9.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/buildkite/agent/v3 v3.101.0 // indirect
|
||||
github.com/buildkite/go-pipeline v0.14.0 // indirect
|
||||
github.com/buildkite/interpolate v0.1.5 // indirect
|
||||
github.com/buildkite/roko v1.3.1 // indirect
|
||||
github.com/bytedance/sonic v1.13.3 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
|
||||
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.14.1 // indirect
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.2 // indirect
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.22.9 // indirect
|
||||
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
|
||||
github.com/digitorus/timestamp v0.0.0-20250524132541-c45532741eea // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/djherbis/times v1.6.0 // indirect
|
||||
github.com/docker/cli v28.3.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||
github.com/emicklei/proto v1.14.2 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-chi/chi v4.1.2+incompatible // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/loads v0.22.0 // indirect
|
||||
github.com/go-openapi/runtime v0.28.0 // indirect
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/go-piv/piv-go/v2 v2.3.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.17.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/certificate-transparency-go v1.3.2 // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-containerregistry v0.20.6 // indirect
|
||||
github.com/google/go-github/v72 v72.0.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
github.com/in-toto/attestation v1.1.2 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.9.1-0.20240317085821-8e2966059a09 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jedisct1/go-minisign v0.0.0-20241212093149-d2f9f49435c7 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/leodido/go-urn v1.3.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/letsencrypt/boulder v0.20250701.0 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mozillazg/docker-credential-acr-helper v0.4.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
||||
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/oleiade/reflections v1.1.0 // indirect
|
||||
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.23.3 // indirect
|
||||
github.com/open-policy-agent/gatekeeper/v3 v3.19.2 // indirect
|
||||
github.com/open-policy-agent/opa v1.6.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/procfs v0.17.0 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20250627152318-f293424e46b5 // indirect
|
||||
github.com/r3labs/diff v1.1.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
github.com/sassoftware/relic v7.2.1+incompatible // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
|
||||
github.com/segmentio/ksuid v1.0.4 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/sigstore/cosign/v2 v2.5.2 // indirect
|
||||
github.com/sigstore/fulcio v1.7.1 // indirect
|
||||
github.com/sigstore/protobuf-specs v0.4.3 // indirect
|
||||
github.com/sigstore/rekor v1.3.10 // indirect
|
||||
github.com/sigstore/sigstore v1.9.5 // indirect
|
||||
github.com/sigstore/sigstore-go v1.0.0 // indirect
|
||||
github.com/sigstore/timestamp-authority v1.2.8 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
|
||||
github.com/tchap/go-patricia/v2 v2.3.3 // indirect
|
||||
github.com/tektoncd/chains v0.25.1 // indirect
|
||||
github.com/thales-e-security/pool v0.0.2 // indirect
|
||||
github.com/theupdateframework/go-tuf v0.7.0 // indirect
|
||||
github.com/theupdateframework/go-tuf/v2 v2.1.1 // indirect
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/transparency-dev/merkle v0.0.2 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/vbatts/tar-split v0.12.1 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.5.30 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/yashtewari/glob-intersection v0.2.0 // indirect
|
||||
github.com/zeebo/errs v1.4.0 // indirect
|
||||
gitlab.com/gitlab-org/api/client-go v0.134.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.step.sm/crypto v0.67.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.7.0 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
|
||||
golang.org/x/oauth2 v0.16.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/term v0.16.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.18.0 // indirect
|
||||
golang.org/x/crypto v0.39.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
google.golang.org/api v0.240.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/grpc v1.73.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/component-base v0.29.1 // indirect
|
||||
k8s.io/klog/v2 v2.120.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec // indirect
|
||||
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
k8s.io/component-base v0.33.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect
|
||||
k8s.io/kubectl v0.33.2 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.21.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/release-utils v0.11.1 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
||||
sigs.k8s.io/yaml v1.5.0 // indirect
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/cmd"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/cmd"
|
||||
)
|
||||
|
||||
var Version = "development"
|
||||
|
|
|
@ -3,8 +3,8 @@ package config
|
|||
import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/kubernetes/secrets"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/logging"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/secrets"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/logging"
|
||||
)
|
||||
|
||||
type BasicAuth struct {
|
||||
|
@ -34,11 +34,17 @@ type LeaderElection struct {
|
|||
Enabled bool `mapstructure:"enabled"`
|
||||
}
|
||||
|
||||
type PolicyReport struct {
|
||||
Labels map[string]string `mapstructure:"labels"`
|
||||
Annotations map[string]string `mapstructure:"annotations"`
|
||||
}
|
||||
|
||||
type BlockReports struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
Results Results `mapstructure:"results"`
|
||||
Source string `mapstructure:"source"`
|
||||
EventNamespace string `mapstructure:"eventNamespace"`
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
Results Results `mapstructure:"results"`
|
||||
Source string `mapstructure:"source"`
|
||||
EventNamespace string `mapstructure:"eventNamespace"`
|
||||
PolicyReport PolicyReport `mapstructure:"policyReport"`
|
||||
}
|
||||
|
||||
type CoreAPI struct {
|
||||
|
|
|
@ -2,20 +2,21 @@ package config
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func Load(c *Config, cfgFile string) error {
|
||||
v := viper.New()
|
||||
v := viper.NewWithOptions(viper.KeyDelimiter("!"))
|
||||
|
||||
if cfgFile != "" {
|
||||
v.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
v.AddConfigPath(".")
|
||||
v.SetConfigName("config")
|
||||
v.AllKeys()
|
||||
}
|
||||
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
|
@ -25,15 +26,18 @@ func Load(c *Config, cfgFile string) error {
|
|||
fmt.Printf("[INFO] No configuration file found: %v\n", err)
|
||||
}
|
||||
|
||||
if err := v.BindEnv("leaderElection.podName", "POD_NAME"); err != nil {
|
||||
zap.L().Warn("failed to bind env POD_NAME")
|
||||
}
|
||||
|
||||
if err := v.BindEnv("namespace", "POD_NAMESPACE"); err != nil {
|
||||
zap.L().Warn("failed to bind env POD_NAMESPACE")
|
||||
}
|
||||
|
||||
err := v.Unmarshal(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
if c.LeaderElection.PodName == "" {
|
||||
c.LeaderElection.PodName = os.Getenv("POD_NAME")
|
||||
}
|
||||
|
||||
if c.Namespace == "" {
|
||||
c.Namespace = os.Getenv("POD_NAMESPACE")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -12,17 +12,20 @@ import (
|
|||
"k8s.io/client-go/metadata"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/core"
|
||||
kyvernov1 "github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/crd/client/clientset/versioned/typed/kyverno/v1"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/kubernetes/events"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/kubernetes/kyverno"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/kubernetes/leaderelection"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/kubernetes/policyreport"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/kubernetes/secrets"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/logging"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/server"
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/violation"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/core"
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/client/clientset/versioned/typed/kyverno/v1"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/client/clientset/versioned/typed/policies.kyverno.io/v1alpha1"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/client/clientset/versioned/typed/policyreport/v1alpha2"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/events"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/kyverno/ivpol"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/kyverno/pol"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/kyverno/vpol"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/leaderelection"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/policyreport"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/kubernetes/secrets"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/logging"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/server"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/violation"
|
||||
)
|
||||
|
||||
type Resolver struct {
|
||||
|
@ -34,7 +37,9 @@ type Resolver struct {
|
|||
secrets secrets.Client
|
||||
leaderClient *leaderelection.Client
|
||||
polrClient policyreport.Client
|
||||
kyvernoClient kyverno.Client
|
||||
kyvernoClient pol.Client
|
||||
vpolClient vpol.Client
|
||||
ivpolClient ivpol.Client
|
||||
eventClient violation.EventClient
|
||||
}
|
||||
|
||||
|
@ -132,7 +137,7 @@ func (r *Resolver) KyvernoV1Client() (kyvernov1.KyvernoV1Interface, error) {
|
|||
return client, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) KyvernoClient() (kyverno.Client, error) {
|
||||
func (r *Resolver) KyvernoClient() (pol.Client, error) {
|
||||
if r.kyvernoClient != nil {
|
||||
return r.kyvernoClient, nil
|
||||
}
|
||||
|
@ -152,11 +157,90 @@ func (r *Resolver) KyvernoClient() (kyverno.Client, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
r.kyvernoClient = kyverno.NewClient(m, d, k, gocache.New(15*time.Second, 5*time.Second))
|
||||
c, err := r.CoreClient(context.TODO())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.kyvernoClient = pol.NewClient(m, d, k, c, gocache.New(15*time.Second, 5*time.Second))
|
||||
|
||||
return r.kyvernoClient, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) PoliciesV1Alpha1Client() (*v1alpha1.PoliciesV1alpha1Client, error) {
|
||||
k8sConfig, err := r.K8sConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := v1alpha1.NewForConfig(k8sConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) VPOLClient() (vpol.Client, error) {
|
||||
if r.vpolClient != nil {
|
||||
return r.vpolClient, nil
|
||||
}
|
||||
|
||||
m, err := r.MetadataClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d, err := r.DynamicClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k, err := r.PoliciesV1Alpha1Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := r.CoreClient(context.TODO())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.vpolClient = vpol.NewClient(m, d, k.ValidatingPolicies(), c, gocache.New(15*time.Second, 5*time.Second))
|
||||
|
||||
return r.vpolClient, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) IVPOLClient() (ivpol.Client, error) {
|
||||
if r.ivpolClient != nil {
|
||||
return r.ivpolClient, nil
|
||||
}
|
||||
|
||||
m, err := r.MetadataClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d, err := r.DynamicClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k, err := r.PoliciesV1Alpha1Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := r.CoreClient(context.TODO())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.ivpolClient = ivpol.NewClient(m, d, k.ImageValidatingPolicies(), c, gocache.New(15*time.Second, 5*time.Second))
|
||||
|
||||
return r.ivpolClient, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) Logger() *zap.Logger {
|
||||
return logging.New(r.config.Logging)
|
||||
}
|
||||
|
@ -185,7 +269,7 @@ func (r *Resolver) Server(ctx context.Context, options []server.ServerOption) (*
|
|||
engine := gin.New()
|
||||
defaults := []server.ServerOption{server.WithGZIP()}
|
||||
|
||||
if r.config.Logging.Enabled || r.config.Server.Debug {
|
||||
if r.config.Logging.Server || r.config.Server.Debug {
|
||||
defaults = append(defaults, server.WithLogging(zap.L()))
|
||||
} else {
|
||||
defaults = append(defaults, server.WithRecovery())
|
||||
|
@ -236,11 +320,21 @@ func (r *Resolver) PolicyReportClient() (policyreport.Client, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if r.config.BlockReports.PolicyReport.Labels == nil {
|
||||
r.config.BlockReports.PolicyReport.Labels = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
if r.config.BlockReports.PolicyReport.Annotations == nil {
|
||||
r.config.BlockReports.PolicyReport.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
policyreportClient := policyreport.NewClient(
|
||||
client,
|
||||
r.config.BlockReports.Results.MaxPerReport,
|
||||
r.config.BlockReports.Source,
|
||||
r.config.BlockReports.Results.KeepOnlyLatest,
|
||||
r.config.BlockReports.PolicyReport.Labels,
|
||||
r.config.BlockReports.PolicyReport.Annotations,
|
||||
)
|
||||
|
||||
r.polrClient = policyreportClient
|
||||
|
@ -315,7 +409,7 @@ func (r *Resolver) CoreClient(ctx context.Context) (*core.Client, error) {
|
|||
}))
|
||||
}
|
||||
|
||||
if r.config.Logging.Enabled && r.config.Logging.LogLevel < 0 {
|
||||
if r.config.Logging.API && r.config.Logging.LogLevel < 0 {
|
||||
options = append(options, core.WithLogging())
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,16 @@ type Client struct {
|
|||
auth *BasicAuth
|
||||
}
|
||||
|
||||
func (c *Client) GetPropertyValues(ctx context.Context, property string, query url.Values) ([]ResultProperty, error) {
|
||||
resp, err := c.get(ctx, fmt.Sprintf("/v2/properties/%s", property), query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return decodeList[ResultProperty](resp.Body)
|
||||
}
|
||||
|
||||
func (c *Client) GetResource(ctx context.Context, id string) (*Resource, error) {
|
||||
resp, err := c.get(ctx, fmt.Sprintf("/v2/resource/%s", id), url.Values{})
|
||||
if err != nil {
|
||||
|
|
|
@ -9,6 +9,11 @@ type Category struct {
|
|||
Fail int `json:"fail"`
|
||||
}
|
||||
|
||||
type ResultProperty struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Property string `json:"property"`
|
||||
}
|
||||
|
||||
type Resource struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
UID string `json:"uid,omitempty"`
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
package api
|
|
@ -0,0 +1,61 @@
|
|||
package kyverno
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
type Value any
|
||||
|
||||
// Any can be any type.
|
||||
// +k8s:deepcopy-gen=false
|
||||
type Any struct {
|
||||
// Value contains the value of the Any object.
|
||||
// +optional
|
||||
Value `json:"-"`
|
||||
}
|
||||
|
||||
func ToAny(in any) *Any {
|
||||
var new *Any
|
||||
if in != nil {
|
||||
new = &Any{in}
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
func FromAny(in *Any) any {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
return in.Value
|
||||
}
|
||||
|
||||
func (in *Any) DeepCopyInto(out *Any) {
|
||||
if err := copier.Copy(out, in); err != nil {
|
||||
panic("deep copy failed")
|
||||
}
|
||||
}
|
||||
|
||||
func (in *Any) DeepCopy() *Any {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Any)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (a *Any) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(a.Value)
|
||||
}
|
||||
|
||||
func (a *Any) UnmarshalJSON(data []byte) error {
|
||||
var v any
|
||||
err := json.Unmarshal(data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Value = v
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package kyverno
|
||||
|
||||
const (
|
||||
// Well known labels
|
||||
LabelAppComponent = "app.kubernetes.io/component"
|
||||
LabelAppManagedBy = "app.kubernetes.io/managed-by"
|
||||
LabelCacheEnabled = "cache.kyverno.io/enabled"
|
||||
LabelCertManagedBy = "cert.kyverno.io/managed-by"
|
||||
LabelCleanupTtl = "cleanup.kyverno.io/ttl"
|
||||
LabelWebhookManagedBy = "webhook.kyverno.io/managed-by"
|
||||
// Well known annotations
|
||||
AnnotationAutogenControllers = "pod-policies.kyverno.io/autogen-controllers"
|
||||
AnnotationImageVerify = "kyverno.io/verify-images"
|
||||
AnnotationImageVerifyOutcomes = "kyverno.io/image-verification-outcomes"
|
||||
AnnotationPolicyCategory = "policies.kyverno.io/category"
|
||||
AnnotationPolicyScored = "policies.kyverno.io/scored"
|
||||
AnnotationPolicySeverity = "policies.kyverno.io/severity"
|
||||
AnnotationCleanupPropagationPolicy = "cleanup.kyverno.io/propagation-policy"
|
||||
// Well known values
|
||||
ValueKyvernoApp = "kyverno"
|
||||
ValueTtlDateTimeLayout = "2006-01-02T150405Z"
|
||||
ValueTtlDateLayout = "2006-01-02"
|
||||
)
|
|
@ -1,8 +1,6 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -12,68 +10,29 @@ import (
|
|||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=clusterpolicies,scope="Cluster",shortName=cpol,categories=kyverno
|
||||
// +kubebuilder:printcolumn:name="Background",type=boolean,JSONPath=".spec.background"
|
||||
// +kubebuilder:printcolumn:name="Validate Action",type=string,JSONPath=".spec.validationFailureAction"
|
||||
// +kubebuilder:printcolumn:name="Failure Policy",type=string,JSONPath=".spec.failurePolicy",priority=1
|
||||
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="Validate",type=integer,JSONPath=`.status.rulecount.validate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="Mutate",type=integer,JSONPath=`.status.rulecount.mutate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="Generate",type=integer,JSONPath=`.status.rulecount.generate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="Verifyimages",type=integer,JSONPath=`.status.rulecount.verifyimages`,priority=1
|
||||
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
|
||||
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1
|
||||
// +kubebuilder:printcolumn:name="VALIDATE",type=integer,JSONPath=`.status.rulecount.validate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MUTATE",type=integer,JSONPath=`.status.rulecount.mutate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="GENERATE",type=integer,JSONPath=`.status.rulecount.generate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="VERIFY IMAGES",type=integer,JSONPath=`.status.rulecount.verifyimages`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MESSAGE",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].message`
|
||||
// +kubebuilder:storageversion
|
||||
|
||||
// ClusterPolicy declares validation, mutation, and generation behaviors for matching resources.
|
||||
type ClusterPolicy struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
metav1.TypeMeta `json:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec declares policy behaviors.
|
||||
Spec Spec `json:"spec" yaml:"spec"`
|
||||
Spec Spec `json:"spec"`
|
||||
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status PolicyStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
||||
}
|
||||
|
||||
// HasAutoGenAnnotation checks if a policy has auto-gen annotation
|
||||
func (p *ClusterPolicy) HasAutoGenAnnotation() bool {
|
||||
annotations := p.GetAnnotations()
|
||||
val, ok := annotations[PodControllersAnnotation]
|
||||
if ok && strings.ToLower(val) != "none" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasMutateOrValidateOrGenerate checks for rule types
|
||||
func (p *ClusterPolicy) HasMutateOrValidateOrGenerate() bool {
|
||||
for _, rule := range p.Spec.Rules {
|
||||
if rule.HasMutate() || rule.HasValidate() || rule.HasGenerate() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasMutate checks for mutate rule types
|
||||
func (p *ClusterPolicy) HasMutate() bool {
|
||||
return p.Spec.HasMutate()
|
||||
}
|
||||
|
||||
// HasValidate checks for validate rule types
|
||||
func (p *ClusterPolicy) HasValidate() bool {
|
||||
return p.Spec.HasValidate()
|
||||
}
|
||||
|
||||
// HasGenerate checks for generate rule types
|
||||
func (p *ClusterPolicy) HasGenerate() bool {
|
||||
return p.Spec.HasGenerate()
|
||||
}
|
||||
|
||||
// HasVerifyImages checks for image verification rule types
|
||||
func (p *ClusterPolicy) HasVerifyImages() bool {
|
||||
return p.Spec.HasVerifyImages()
|
||||
Status PolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetSpec returns the policy spec
|
||||
|
@ -88,34 +47,23 @@ func (p *ClusterPolicy) GetStatus() *PolicyStatus {
|
|||
|
||||
// IsNamespaced indicates if the policy is namespace scoped
|
||||
func (p *ClusterPolicy) IsNamespaced() bool {
|
||||
return p.GetNamespace() != ""
|
||||
return false
|
||||
}
|
||||
|
||||
// IsReady indicates if the policy is ready to serve the admission request
|
||||
func (p *ClusterPolicy) IsReady() bool {
|
||||
return p.Status.IsReady()
|
||||
}
|
||||
|
||||
func (p *ClusterPolicy) GetKind() string {
|
||||
return p.Kind
|
||||
}
|
||||
|
||||
func (p *ClusterPolicy) GetAPIVersion() string {
|
||||
return p.APIVersion
|
||||
}
|
||||
|
||||
func (p *ClusterPolicy) SetKind(value string) {
|
||||
p.Kind = value
|
||||
}
|
||||
|
||||
func (p *ClusterPolicy) SetAPIVersion(value string) {
|
||||
p.APIVersion = value
|
||||
}
|
||||
|
||||
func (p *ClusterPolicy) CreateDeepCopy() PolicyInterface {
|
||||
return p.DeepCopy()
|
||||
return "ClusterPolicy"
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterPolicyList is a list of ClusterPolicy instances.
|
||||
type ClusterPolicyList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []ClusterPolicy `json:"items" yaml:"items"`
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []ClusterPolicy `json:"items"`
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
kjson "github.com/kyverno/kyverno-json/pkg/apis/policy/v1alpha1"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno"
|
||||
"github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/pod-security-admission/api"
|
||||
)
|
||||
|
||||
// AssertionTree defines a kyverno-json assertion tree.
|
||||
type AssertionTree = kjson.Any
|
||||
|
||||
// FailurePolicyType specifies a failure policy that defines how unrecognized errors from the admission endpoint are handled.
|
||||
// +kubebuilder:validation:Enum=Ignore;Fail
|
||||
type FailurePolicyType string
|
||||
|
@ -29,6 +36,37 @@ const (
|
|||
ApplyOne ApplyRulesType = "One"
|
||||
)
|
||||
|
||||
// ForeachOrder specifies the iteration order in foreach statements.
|
||||
// +kubebuilder:validation:Enum=Ascending;Descending
|
||||
type ForeachOrder string
|
||||
|
||||
const (
|
||||
// Ascending means iterating from first to last element.
|
||||
Ascending ForeachOrder = "Ascending"
|
||||
// Descending means iterating from last to first element.
|
||||
Descending ForeachOrder = "Descending"
|
||||
)
|
||||
|
||||
// WebhookConfiguration specifies the configuration for Kubernetes admission webhookconfiguration.
|
||||
type WebhookConfiguration struct {
|
||||
// FailurePolicy defines how unexpected policy errors and webhook response timeout errors are handled.
|
||||
// Rules within the same policy share the same failure behavior.
|
||||
// This field should not be accessed directly, instead `GetFailurePolicy()` should be used.
|
||||
// Allowed values are Ignore or Fail. Defaults to Fail.
|
||||
// +optional
|
||||
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty"`
|
||||
|
||||
// TimeoutSeconds specifies the maximum time in seconds allowed to apply this policy.
|
||||
// After the configured time expires, the admission request may fail, or may simply ignore the policy results,
|
||||
// based on the failure policy. The default timeout is 10s, the value must be between 1 and 30 seconds.
|
||||
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"`
|
||||
|
||||
// MatchCondition configures admission webhook matchConditions.
|
||||
// Requires Kubernetes 1.27 or later.
|
||||
// +optional
|
||||
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty"`
|
||||
}
|
||||
|
||||
// AnyAllConditions consists of conditions wrapped denoting a logical criteria to be fulfilled.
|
||||
// AnyConditions get fulfilled when at least one of its sub-conditions passes.
|
||||
// AllConditions get fulfilled only when all of its sub-conditions pass.
|
||||
|
@ -38,52 +76,64 @@ type AnyAllConditions struct {
|
|||
// using JMESPath notation.
|
||||
// Here, at least one of the conditions need to pass
|
||||
// +optional
|
||||
AnyConditions []Condition `json:"any,omitempty" yaml:"any,omitempty"`
|
||||
AnyConditions []Condition `json:"any,omitempty"`
|
||||
|
||||
// AllConditions enable variable-based conditional rule execution. This is useful for
|
||||
// finer control of when an rule is applied. A condition can reference object data
|
||||
// using JMESPath notation.
|
||||
// Here, all of the conditions need to pass
|
||||
// +optional
|
||||
AllConditions []Condition `json:"all,omitempty" yaml:"all,omitempty"`
|
||||
AllConditions []Condition `json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// ContextEntry adds variables and data sources to a rule Context. Either a
|
||||
// ConfigMap reference or a APILookup must be provided.
|
||||
// +kubebuilder:oneOf:={required:{configMap}}
|
||||
// +kubebuilder:oneOf:={required:{apiCall}}
|
||||
// +kubebuilder:oneOf:={required:{imageRegistry}}
|
||||
// +kubebuilder:oneOf:={required:{variable}}
|
||||
// +kubebuilder:oneOf:={required:{globalReference}}
|
||||
type ContextEntry struct {
|
||||
// Name is the variable name.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Name string `json:"name"`
|
||||
|
||||
// ConfigMap is the ConfigMap reference.
|
||||
ConfigMap *ConfigMapReference `json:"configMap,omitempty" yaml:"configMap,omitempty"`
|
||||
ConfigMap *ConfigMapReference `json:"configMap,omitempty"`
|
||||
|
||||
// APICall is an HTTP request to the Kubernetes API server, or other JSON web service.
|
||||
// The data returned is stored in the context with the name for the context entry.
|
||||
APICall *APICall `json:"apiCall,omitempty" yaml:"apiCall,omitempty"`
|
||||
APICall *ContextAPICall `json:"apiCall,omitempty"`
|
||||
|
||||
// ImageRegistry defines requests to an OCI/Docker V2 registry to fetch image
|
||||
// details.
|
||||
ImageRegistry *ImageRegistry `json:"imageRegistry,omitempty" yaml:"imageRegistry,omitempty"`
|
||||
ImageRegistry *ImageRegistry `json:"imageRegistry,omitempty"`
|
||||
|
||||
// Variable defines an arbitrary JMESPath context variable that can be defined inline.
|
||||
Variable *Variable `json:"variable,omitempty" yaml:"variable,omitempty"`
|
||||
Variable *Variable `json:"variable,omitempty"`
|
||||
|
||||
// GlobalContextEntryReference is a reference to a cached global context entry.
|
||||
GlobalReference *GlobalContextEntryReference `json:"globalReference,omitempty"`
|
||||
}
|
||||
|
||||
// Variable defines an arbitrary JMESPath context variable that can be defined inline.
|
||||
type Variable struct {
|
||||
// Value is any arbitrary JSON object representable in YAML or JSON form.
|
||||
// +optional
|
||||
Value *apiextv1.JSON `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Value *kyverno.Any `json:"value,omitempty"`
|
||||
|
||||
// JMESPath is an optional JMESPath Expression that can be used to
|
||||
// transform the variable.
|
||||
// +optional
|
||||
JMESPath string `json:"jmesPath,omitempty" yaml:"jmesPath,omitempty"`
|
||||
JMESPath string `json:"jmesPath,omitempty"`
|
||||
|
||||
// Default is an optional arbitrary JSON object that the variable may take if the JMESPath
|
||||
// expression evaluates to nil
|
||||
// +optional
|
||||
Default *apiextv1.JSON `json:"default,omitempty" yaml:"default,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Default *kyverno.Any `json:"default,omitempty"`
|
||||
}
|
||||
|
||||
// ImageRegistry defines requests to an OCI/Docker V2 registry to fetch image
|
||||
|
@ -91,34 +141,61 @@ type Variable struct {
|
|||
type ImageRegistry struct {
|
||||
// Reference is image reference to a container image in the registry.
|
||||
// Example: ghcr.io/kyverno/kyverno:latest
|
||||
Reference string `json:"reference" yaml:"reference"`
|
||||
Reference string `json:"reference"`
|
||||
|
||||
// JMESPath is an optional JSON Match Expression that can be used to
|
||||
// transform the ImageData struct returned as a result of processing
|
||||
// the image reference.
|
||||
// +optional
|
||||
JMESPath string `json:"jmesPath,omitempty" yaml:"jmesPath,omitempty"`
|
||||
JMESPath string `json:"jmesPath,omitempty"`
|
||||
|
||||
// ImageRegistryCredentials provides credentials that will be used for authentication with registry
|
||||
// +kubebuilder:validation:Optional
|
||||
ImageRegistryCredentials *ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty"`
|
||||
}
|
||||
|
||||
// ConfigMapReference refers to a ConfigMap
|
||||
type ConfigMapReference struct {
|
||||
// Name is the ConfigMap name.
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace is the ConfigMap namespace.
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
type APICall struct {
|
||||
// URLPath is the URL path to be used in the HTTP GET request to the
|
||||
// URLPath is the URL path to be used in the HTTP GET or POST request to the
|
||||
// Kubernetes API server (e.g. "/api/v1/namespaces" or "/apis/apps/v1/deployments").
|
||||
// The format required is the same format used by the `kubectl get --raw` command.
|
||||
// See https://kyverno.io/docs/writing-policies/external-data-sources/#variables-from-kubernetes-api-server-calls
|
||||
// for details.
|
||||
// It's mutually exclusive with the Service field.
|
||||
// +kubebuilder:validation:Optional
|
||||
URLPath string `json:"urlPath" yaml:"urlPath"`
|
||||
URLPath string `json:"urlPath"`
|
||||
|
||||
// Service is an API call to a JSON web service
|
||||
// Method is the HTTP request type (GET or POST). Defaults to GET.
|
||||
// +kubebuilder:default=GET
|
||||
Method Method `json:"method,omitempty"`
|
||||
|
||||
// The data object specifies the POST data sent to the server.
|
||||
// Only applicable when the method field is set to POST.
|
||||
// +kubebuilder:validation:Optional
|
||||
Service *ServiceCall `json:"service,omitempty" yaml:"service,omitempty"`
|
||||
Data []RequestData `json:"data,omitempty"`
|
||||
|
||||
// Service is an API call to a JSON web service.
|
||||
// This is used for non-Kubernetes API server calls.
|
||||
// It's mutually exclusive with the URLPath field.
|
||||
// +kubebuilder:validation:Optional
|
||||
Service *ServiceCall `json:"service,omitempty"`
|
||||
}
|
||||
|
||||
type ContextAPICall struct {
|
||||
APICall `json:",inline"`
|
||||
|
||||
// Default is an optional arbitrary JSON object that the context
|
||||
// value is set to, if the apiCall returns error.
|
||||
// +optional
|
||||
Default *apiextv1.JSON `json:"default,omitempty"`
|
||||
|
||||
// JMESPath is an optional JSON Match Expression that can be used to
|
||||
// transform the JSON response returned from the server. For example
|
||||
|
@ -126,26 +203,35 @@ type APICall struct {
|
|||
// for the URLPath "/apis/apps/v1/deployments" will return the total count
|
||||
// of deployments across all namespaces.
|
||||
// +kubebuilder:validation:Optional
|
||||
JMESPath string `json:"jmesPath,omitempty" yaml:"jmesPath,omitempty"`
|
||||
JMESPath string `json:"jmesPath,omitempty"`
|
||||
}
|
||||
|
||||
type GlobalContextEntryReference struct {
|
||||
// Name of the global context entry
|
||||
// +kubebuilder:validation:Required
|
||||
Name string `json:"name"`
|
||||
|
||||
// JMESPath is an optional JSON Match Expression that can be used to
|
||||
// transform the JSON response returned from the server. For example
|
||||
// a JMESPath of "items | length(@)" applied to the API server response
|
||||
// for the URLPath "/apis/apps/v1/deployments" will return the total count
|
||||
// of deployments across all namespaces.
|
||||
// +kubebuilder:validation:Optional
|
||||
JMESPath string `json:"jmesPath,omitempty"`
|
||||
}
|
||||
|
||||
type ServiceCall struct {
|
||||
// URL is the JSON web service URL.
|
||||
// The typical format is `https://{service}.{namespace}:{port}/{path}`.
|
||||
URL string `json:"urlPath" yaml:"urlPath"`
|
||||
// URL is the JSON web service URL. A typical form is
|
||||
// `https://{service}.{namespace}:{port}/{path}`.
|
||||
URL string `json:"url"`
|
||||
|
||||
// Headers is a list of optional HTTP headers to be included in the request.
|
||||
Headers []HTTPHeader `json:"headers,omitempty"`
|
||||
|
||||
// CABundle is a PEM encoded CA bundle which will be used to validate
|
||||
// the server certificate.
|
||||
// +kubebuilder:validation:Optional
|
||||
CABundle string `json:"caBundle" yaml:"caBundle"`
|
||||
|
||||
// Method is the HTTP request type (GET or POST).
|
||||
// +kubebuilder:default=GET
|
||||
Method Method `json:"requestType" yaml:"requestType"`
|
||||
|
||||
// Data specifies the POST data sent to the server.
|
||||
// +kubebuilder:validation:Optional
|
||||
Data []RequestData `json:"data" yaml:"data"`
|
||||
CABundle string `json:"caBundle"`
|
||||
}
|
||||
|
||||
// Method is a HTTP request type.
|
||||
|
@ -155,27 +241,37 @@ type Method string
|
|||
// RequestData contains the HTTP POST data
|
||||
type RequestData struct {
|
||||
// Key is a unique identifier for the data value
|
||||
Key string `json:"key" yaml:"key"`
|
||||
Key string `json:"key"`
|
||||
|
||||
// Value is the data value
|
||||
Value *apiextensionsv1.JSON `json:"value" yaml:"value"`
|
||||
Value *apiextv1.JSON `json:"value"`
|
||||
}
|
||||
|
||||
type HTTPHeader struct {
|
||||
// Key is the header key
|
||||
Key string `json:"key"`
|
||||
// Value is the header value
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Condition defines variable-based conditional criteria for rule execution.
|
||||
type Condition struct {
|
||||
// Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
RawKey *apiextv1.JSON `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
RawKey *apiextv1.JSON `json:"key,omitempty"`
|
||||
|
||||
// Operator is the conditional operation to perform. Valid operators are:
|
||||
// Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals,
|
||||
// GreaterThan, LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, DurationGreaterThan,
|
||||
// DurationLessThanOrEquals, DurationLessThan
|
||||
Operator ConditionOperator `json:"operator,omitempty" yaml:"operator,omitempty"`
|
||||
Operator ConditionOperator `json:"operator,omitempty"`
|
||||
|
||||
// Value is the conditional value, or set of values. The values can be fixed set
|
||||
// or can be variables declared using JMESPath.
|
||||
// +optional
|
||||
RawValue *apiextv1.JSON `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
RawValue *apiextv1.JSON `json:"value,omitempty"`
|
||||
|
||||
// Message is an optional display message
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// ConditionOperator is the operation performed on condition key and value.
|
||||
|
@ -230,98 +326,137 @@ type ResourceFilters []ResourceFilter
|
|||
type ResourceFilter struct {
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
// +optional
|
||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||
UserInfo `json:",omitempty"`
|
||||
|
||||
// ResourceDescription contains information about the resource being created or modified.
|
||||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
ResourceDescription `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// Mutation defines how resource are modified.
|
||||
type Mutation struct {
|
||||
// MutateExistingOnPolicyUpdate controls if the mutateExisting rule will be applied on policy events.
|
||||
// +optional
|
||||
MutateExistingOnPolicyUpdate *bool `json:"mutateExistingOnPolicyUpdate,omitempty"`
|
||||
|
||||
// Targets defines the target resources to be mutated.
|
||||
// +optional
|
||||
Targets []ResourceSpec `json:"targets,omitempty" yaml:"targets,omitempty"`
|
||||
Targets []TargetResourceSpec `json:"targets,omitempty"`
|
||||
|
||||
// PatchStrategicMerge is a strategic merge patch used to modify resources.
|
||||
// See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
// and https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/.
|
||||
// and https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesstrategicmerge/.
|
||||
// +optional
|
||||
RawPatchStrategicMerge *apiextv1.JSON `json:"patchStrategicMerge,omitempty" yaml:"patchStrategicMerge,omitempty"`
|
||||
RawPatchStrategicMerge *apiextv1.JSON `json:"patchStrategicMerge,omitempty"`
|
||||
|
||||
// PatchesJSON6902 is a list of RFC 6902 JSON Patch declarations used to modify resources.
|
||||
// See https://tools.ietf.org/html/rfc6902 and https://kubectl.docs.kubernetes.io/references/kustomize/patchesjson6902/.
|
||||
// See https://tools.ietf.org/html/rfc6902 and https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesjson6902/.
|
||||
// +optional
|
||||
PatchesJSON6902 string `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"`
|
||||
PatchesJSON6902 string `json:"patchesJson6902,omitempty"`
|
||||
|
||||
// ForEach applies mutation rules to a list of sub-elements by creating a context for each entry in the list and looping over it to apply the specified logic.
|
||||
// +optional
|
||||
ForEachMutation []ForEachMutation `json:"foreach,omitempty" yaml:"foreach,omitempty"`
|
||||
ForEachMutation []ForEachMutation `json:"foreach,omitempty"`
|
||||
}
|
||||
|
||||
// ForEachMutation applies mutation rules to a list of sub-elements by creating a context for each entry in the list and looping over it to apply the specified logic.
|
||||
type ForEachMutation struct {
|
||||
// List specifies a JMESPath expression that results in one or more elements
|
||||
// to which the validation logic is applied.
|
||||
List string `json:"list,omitempty" yaml:"list,omitempty"`
|
||||
List string `json:"list,omitempty"`
|
||||
|
||||
// Order defines the iteration order on the list.
|
||||
// Can be Ascending to iterate from first to last element or Descending to iterate in from last to first element.
|
||||
// +optional
|
||||
Order *ForeachOrder `json:"order,omitempty"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []ContextEntry `json:"context,omitempty" yaml:"context,omitempty"`
|
||||
Context []ContextEntry `json:"context,omitempty"`
|
||||
|
||||
// AnyAllConditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements.
|
||||
// See: https://kyverno.io/docs/writing-policies/preconditions/
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +optional
|
||||
AnyAllConditions *AnyAllConditions `json:"preconditions,omitempty" yaml:"preconditions,omitempty"`
|
||||
AnyAllConditions *AnyAllConditions `json:"preconditions,omitempty"`
|
||||
|
||||
// PatchStrategicMerge is a strategic merge patch used to modify resources.
|
||||
// See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
// and https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/.
|
||||
// and https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesstrategicmerge/.
|
||||
// +optional
|
||||
RawPatchStrategicMerge *apiextv1.JSON `json:"patchStrategicMerge,omitempty" yaml:"patchStrategicMerge,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawPatchStrategicMerge *kyverno.Any `json:"patchStrategicMerge,omitempty"`
|
||||
|
||||
// PatchesJSON6902 is a list of RFC 6902 JSON Patch declarations used to modify resources.
|
||||
// See https://tools.ietf.org/html/rfc6902 and https://kubectl.docs.kubernetes.io/references/kustomize/patchesjson6902/.
|
||||
// See https://tools.ietf.org/html/rfc6902 and https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesjson6902/.
|
||||
// +optional
|
||||
PatchesJSON6902 string `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"`
|
||||
PatchesJSON6902 string `json:"patchesJson6902,omitempty"`
|
||||
|
||||
// Foreach declares a nested foreach iterator
|
||||
// +optional
|
||||
ForEachMutation *apiextv1.JSON `json:"foreach,omitempty" yaml:"foreach,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
ForEachMutation *ForEachMutationWrapper `json:"foreach,omitempty"`
|
||||
}
|
||||
|
||||
// Validation defines checks to be performed on matching resources.
|
||||
type Validation struct {
|
||||
// FailureAction defines if a validation policy rule violation should block
|
||||
// the admission review request (Enforce), or allow (Audit) the admission review request
|
||||
// and report an error in a policy report. Optional.
|
||||
// Allowed values are Audit or Enforce.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Audit;Enforce
|
||||
FailureAction *ValidationFailureAction `json:"failureAction,omitempty"`
|
||||
|
||||
// FailureActionOverrides is a Cluster Policy attribute that specifies FailureAction
|
||||
// namespace-wise. It overrides FailureAction for the specified namespaces.
|
||||
// +optional
|
||||
FailureActionOverrides []ValidationFailureActionOverride `json:"failureActionOverrides,omitempty"`
|
||||
|
||||
// AllowExistingViolations allows prexisting violating resources to continue violating a policy.
|
||||
// +kubebuilder:validation:Optional
|
||||
// +kubebuilder:default=true
|
||||
AllowExistingViolations *bool `json:"allowExistingViolations,omitempty"`
|
||||
|
||||
// Message specifies a custom message to be displayed on failure.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty" yaml:"message,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// Manifest specifies conditions for manifest verification
|
||||
// +optional
|
||||
Manifests *Manifests `json:"manifests,omitempty" yaml:"manifests,omitempty"`
|
||||
Manifests *Manifests `json:"manifests,omitempty"`
|
||||
|
||||
// ForEach applies validate rules to a list of sub-elements by creating a context for each entry in the list and looping over it to apply the specified logic.
|
||||
// +optional
|
||||
ForEachValidation []ForEachValidation `json:"foreach,omitempty" yaml:"foreach,omitempty"`
|
||||
ForEachValidation []ForEachValidation `json:"foreach,omitempty"`
|
||||
|
||||
// Pattern specifies an overlay-style pattern used to check resources.
|
||||
// +optional
|
||||
RawPattern *apiextv1.JSON `json:"pattern,omitempty" yaml:"pattern,omitempty"`
|
||||
RawPattern *apiextv1.JSON `json:"pattern,omitempty"`
|
||||
|
||||
// AnyPattern specifies list of validation patterns. At least one of the patterns
|
||||
// must be satisfied for the validation rule to succeed.
|
||||
// +optional
|
||||
RawAnyPattern *apiextv1.JSON `json:"anyPattern,omitempty" yaml:"anyPattern,omitempty"`
|
||||
RawAnyPattern *apiextv1.JSON `json:"anyPattern,omitempty"`
|
||||
|
||||
// Deny defines conditions used to pass or fail a validation rule.
|
||||
// +optional
|
||||
Deny *Deny `json:"deny,omitempty" yaml:"deny,omitempty"`
|
||||
Deny *Deny `json:"deny,omitempty"`
|
||||
|
||||
// PodSecurity applies exemptions for Kubernetes Pod Security admission
|
||||
// by specifying exclusions for Pod Security Standards controls.
|
||||
// +optional
|
||||
PodSecurity *PodSecurity `json:"podSecurity,omitempty" yaml:"podSecurity,omitempty"`
|
||||
PodSecurity *PodSecurity `json:"podSecurity,omitempty"`
|
||||
|
||||
// CEL allows validation checks using the Common Expression Language (https://kubernetes.io/docs/reference/using-api/cel/).
|
||||
// +optional
|
||||
CEL *CEL `json:"cel,omitempty"`
|
||||
|
||||
// Assert defines a kyverno-json assertion tree.
|
||||
// +optional
|
||||
Assert AssertionTree `json:"assert"`
|
||||
}
|
||||
|
||||
// PodSecurity applies exemptions for Kubernetes Pod Security admission
|
||||
|
@ -330,16 +465,16 @@ type PodSecurity struct {
|
|||
// Level defines the Pod Security Standard level to be applied to workloads.
|
||||
// Allowed values are privileged, baseline, and restricted.
|
||||
// +kubebuilder:validation:Enum=privileged;baseline;restricted
|
||||
Level api.Level `json:"level,omitempty" yaml:"level,omitempty"`
|
||||
Level api.Level `json:"level,omitempty"`
|
||||
|
||||
// Version defines the Pod Security Standard versions that Kubernetes supports.
|
||||
// Allowed values are v1.19, v1.20, v1.21, v1.22, v1.23, v1.24, v1.25, latest. Defaults to latest.
|
||||
// +kubebuilder:validation:Enum=v1.19;v1.20;v1.21;v1.22;v1.23;v1.24;v1.25;latest
|
||||
// Allowed values are v1.19, v1.20, v1.21, v1.22, v1.23, v1.24, v1.25, v1.26, v1.27, v1.28, v1.29, latest. Defaults to latest.
|
||||
// +kubebuilder:validation:Enum=v1.19;v1.20;v1.21;v1.22;v1.23;v1.24;v1.25;v1.26;v1.27;v1.28;v1.29;latest
|
||||
// +optional
|
||||
Version string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
// Exclude specifies the Pod Security Standard controls to be excluded.
|
||||
Exclude []PodSecurityStandard `json:"exclude,omitempty" yaml:"exclude,omitempty"`
|
||||
Exclude []PodSecurityStandard `json:"exclude,omitempty"`
|
||||
}
|
||||
|
||||
// PodSecurityStandard specifies the Pod Security Standard controls to be excluded.
|
||||
|
@ -347,14 +482,53 @@ type PodSecurityStandard struct {
|
|||
// ControlName specifies the name of the Pod Security Standard control.
|
||||
// See: https://kubernetes.io/docs/concepts/security/pod-security-standards/
|
||||
// +kubebuilder:validation:Enum=HostProcess;Host Namespaces;Privileged Containers;Capabilities;HostPath Volumes;Host Ports;AppArmor;SELinux;/proc Mount Type;Seccomp;Sysctls;Volume Types;Privilege Escalation;Running as Non-root;Running as Non-root user
|
||||
ControlName string `json:"controlName" yaml:"controlName"`
|
||||
ControlName string `json:"controlName"`
|
||||
|
||||
// Images selects matching containers and applies the container level PSS.
|
||||
// Each image is the image name consisting of the registry address, repository, image, and tag.
|
||||
// Empty list matches no containers, PSS checks are applied at the pod level only.
|
||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// +optional
|
||||
Images []string `json:"images,omitempty" yaml:"images,omitempty"`
|
||||
Images []string `json:"images,omitempty"`
|
||||
|
||||
// RestrictedField selects the field for the given Pod Security Standard control.
|
||||
// When not set, all restricted fields for the control are selected.
|
||||
// +optional
|
||||
RestrictedField string `json:"restrictedField,omitempty"`
|
||||
|
||||
// Values defines the allowed values that can be excluded.
|
||||
// +optional
|
||||
Values []string `json:"values,omitempty"`
|
||||
}
|
||||
|
||||
// CEL allows validation checks using the Common Expression Language (https://kubernetes.io/docs/reference/using-api/cel/).
|
||||
type CEL struct {
|
||||
// Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
|
||||
// Optional. Defaults to "false" if not specified.
|
||||
// +optional
|
||||
// +kubebuilder:default=false
|
||||
Generate *bool `json:"generate,omitempty"`
|
||||
|
||||
// Expressions is a list of CELExpression types.
|
||||
Expressions []admissionregistrationv1.Validation `json:"expressions,omitempty"`
|
||||
|
||||
// ParamKind is a tuple of Group Kind and Version.
|
||||
// +optional
|
||||
ParamKind *admissionregistrationv1.ParamKind `json:"paramKind,omitempty"`
|
||||
|
||||
// ParamRef references a parameter resource.
|
||||
// +optional
|
||||
ParamRef *admissionregistrationv1.ParamRef `json:"paramRef,omitempty"`
|
||||
|
||||
// AuditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request.
|
||||
// +optional
|
||||
AuditAnnotations []admissionregistrationv1.AuditAnnotation `json:"auditAnnotations,omitempty"`
|
||||
|
||||
// Variables contain definitions of variables that can be used in composition of other expressions.
|
||||
// Each variable is defined as a named CEL expression.
|
||||
// The variables defined here will be available under `variables` in other expressions of the policy.
|
||||
// +optional
|
||||
Variables []admissionregistrationv1.Variable `json:"variables,omitempty"`
|
||||
}
|
||||
|
||||
// Deny specifies a list of conditions used to pass or fail a validation rule.
|
||||
|
@ -363,123 +537,175 @@ type Deny struct {
|
|||
// of conditions (without `any` or `all` statements) is also supported for backwards compatibility
|
||||
// but will be deprecated in the next major release.
|
||||
// See: https://kyverno.io/docs/writing-policies/validate/#deny-rules
|
||||
RawAnyAllConditions *apiextv1.JSON `json:"conditions,omitempty" yaml:"conditions,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawAnyAllConditions *ConditionsWrapper `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// ForEachValidation applies validate rules to a list of sub-elements by creating a context for each entry in the list and looping over it to apply the specified logic.
|
||||
type ForEachValidation struct {
|
||||
// List specifies a JMESPath expression that results in one or more elements
|
||||
// to which the validation logic is applied.
|
||||
List string `json:"list,omitempty" yaml:"list,omitempty"`
|
||||
List string `json:"list,omitempty"`
|
||||
|
||||
// ElementScope specifies whether to use the current list element as the scope for validation. Defaults to "true" if not specified.
|
||||
// When set to "false", "request.object" is used as the validation scope within the foreach
|
||||
// block to allow referencing other elements in the subtree.
|
||||
// +optional
|
||||
ElementScope *bool `json:"elementScope,omitempty" yaml:"elementScope,omitempty"`
|
||||
ElementScope *bool `json:"elementScope,omitempty"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []ContextEntry `json:"context,omitempty" yaml:"context,omitempty"`
|
||||
Context []ContextEntry `json:"context,omitempty"`
|
||||
|
||||
// AnyAllConditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements.
|
||||
// See: https://kyverno.io/docs/writing-policies/preconditions/
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +optional
|
||||
AnyAllConditions *AnyAllConditions `json:"preconditions,omitempty" yaml:"preconditions,omitempty"`
|
||||
AnyAllConditions *AnyAllConditions `json:"preconditions,omitempty"`
|
||||
|
||||
// Pattern specifies an overlay-style pattern used to check resources.
|
||||
// +optional
|
||||
RawPattern *apiextv1.JSON `json:"pattern,omitempty" yaml:"pattern,omitempty"`
|
||||
RawPattern *apiextv1.JSON `json:"pattern,omitempty"`
|
||||
|
||||
// AnyPattern specifies list of validation patterns. At least one of the patterns
|
||||
// must be satisfied for the validation rule to succeed.
|
||||
// +optional
|
||||
RawAnyPattern *apiextv1.JSON `json:"anyPattern,omitempty" yaml:"anyPattern,omitempty"`
|
||||
RawAnyPattern *apiextv1.JSON `json:"anyPattern,omitempty"`
|
||||
|
||||
// Deny defines conditions used to pass or fail a validation rule.
|
||||
// +optional
|
||||
Deny *Deny `json:"deny,omitempty" yaml:"deny,omitempty"`
|
||||
Deny *Deny `json:"deny,omitempty"`
|
||||
|
||||
// Foreach declares a nested foreach iterator
|
||||
// +optional
|
||||
ForEachValidation *apiextv1.JSON `json:"foreach,omitempty" yaml:"foreach,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
ForEachValidation *ForEachValidationWrapper `json:"foreach,omitempty"`
|
||||
}
|
||||
|
||||
// Generation defines how new resources should be created and managed.
|
||||
type Generation struct {
|
||||
// ResourceSpec contains information to select the resource.
|
||||
ResourceSpec `json:",omitempty" yaml:",omitempty"`
|
||||
// GenerateExisting controls whether to trigger the rule in existing resources
|
||||
// If is set to "true" the rule will be triggered and applied to existing matched resources.
|
||||
// +optional
|
||||
GenerateExisting *bool `json:"generateExisting,omitempty"`
|
||||
|
||||
// Synchronize controls if generated resources should be kept in-sync with their source resource.
|
||||
// If Synchronize is set to "true" changes to generated resources will be overwritten with resource
|
||||
// data from Data or the resource specified in the Clone declaration.
|
||||
// Optional. Defaults to "false" if not specified.
|
||||
// +optional
|
||||
Synchronize bool `json:"synchronize,omitempty" yaml:"synchronize,omitempty"`
|
||||
Synchronize bool `json:"synchronize,omitempty"`
|
||||
|
||||
// OrphanDownstreamOnPolicyDelete controls whether generated resources should be deleted when the rule that generated
|
||||
// them is deleted with synchronization enabled. This option is only applicable to generate rules of the data type.
|
||||
// See https://kyverno.io/docs/writing-policies/generate/#data-examples.
|
||||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
OrphanDownstreamOnPolicyDelete bool `json:"orphanDownstreamOnPolicyDelete,omitempty"`
|
||||
|
||||
// +optional
|
||||
GeneratePattern `json:",omitempty"`
|
||||
|
||||
// ForEach applies generate rules to a list of sub-elements by creating a context for each entry in the list and looping over it to apply the specified logic.
|
||||
// +optional
|
||||
ForEachGeneration []ForEachGeneration `json:"foreach,omitempty"`
|
||||
}
|
||||
|
||||
type GeneratePattern struct {
|
||||
// ResourceSpec contains information to select the resource.
|
||||
// +kubebuilder:validation:Optional
|
||||
ResourceSpec `json:",omitempty"`
|
||||
|
||||
// Data provides the resource declaration used to populate each generated resource.
|
||||
// At most one of Data or Clone must be specified. If neither are provided, the generated
|
||||
// resource will be created with default data only.
|
||||
// +optional
|
||||
RawData *apiextv1.JSON `json:"data,omitempty" yaml:"data,omitempty"`
|
||||
RawData *apiextv1.JSON `json:"data,omitempty"`
|
||||
|
||||
// Clone specifies the source resource used to populate each generated resource.
|
||||
// At most one of Data or Clone can be specified. If neither are provided, the generated
|
||||
// resource will be created with default data only.
|
||||
// +optional
|
||||
Clone CloneFrom `json:"clone,omitempty" yaml:"clone,omitempty"`
|
||||
Clone CloneFrom `json:"clone,omitempty"`
|
||||
|
||||
// CloneList specifies the list of source resource used to populate each generated resource.
|
||||
// +optional
|
||||
CloneList CloneList `json:"cloneList,omitempty" yaml:"cloneList,omitempty"`
|
||||
CloneList CloneList `json:"cloneList,omitempty"`
|
||||
}
|
||||
|
||||
type ForEachGeneration struct {
|
||||
// List specifies a JMESPath expression that results in one or more elements
|
||||
// to which the validation logic is applied.
|
||||
List string `json:"list,omitempty"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []ContextEntry `json:"context,omitempty"`
|
||||
|
||||
// AnyAllConditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements.
|
||||
// See: https://kyverno.io/docs/writing-policies/preconditions/
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +optional
|
||||
AnyAllConditions *AnyAllConditions `json:"preconditions,omitempty"`
|
||||
|
||||
GeneratePattern `json:",omitempty"`
|
||||
}
|
||||
|
||||
type CloneList struct {
|
||||
// Namespace specifies source resource namespace.
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
|
||||
// Kinds is a list of resource kinds.
|
||||
Kinds []string `json:"kinds,omitempty" yaml:"kinds,omitempty"`
|
||||
Kinds []string `json:"kinds,omitempty"`
|
||||
|
||||
// Selector is a label selector. Label keys and values in `matchLabels`.
|
||||
// wildcard characters are not supported.
|
||||
// +optional
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"`
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
type GenerateType string
|
||||
|
||||
const (
|
||||
Data GenerateType = "Data"
|
||||
Clone GenerateType = "Clone"
|
||||
)
|
||||
|
||||
// CloneFrom provides the location of the source resource used to generate target resources.
|
||||
// The resource kind is derived from the match criteria.
|
||||
type CloneFrom struct {
|
||||
// Namespace specifies source resource namespace.
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
|
||||
// Name specifies name of the resource.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type Manifests struct {
|
||||
// Attestors specified the required attestors (i.e. authorities)
|
||||
// +kubebuilder:validation:Optional
|
||||
Attestors []AttestorSet `json:"attestors,omitempty" yaml:"attestors,omitempty"`
|
||||
Attestors []AttestorSet `json:"attestors,omitempty"`
|
||||
|
||||
// AnnotationDomain is custom domain of annotation for message and signature. Default is "cosign.sigstore.dev".
|
||||
// +optional
|
||||
AnnotationDomain string `json:"annotationDomain,omitempty" yaml:"annotationDomain,omitempty"`
|
||||
AnnotationDomain string `json:"annotationDomain,omitempty"`
|
||||
|
||||
// Fields which will be ignored while comparing manifests.
|
||||
// +optional
|
||||
IgnoreFields IgnoreFieldList `json:"ignoreFields,omitempty" yaml:"ignoreFields,omitempty"`
|
||||
IgnoreFields IgnoreFieldList `json:"ignoreFields,omitempty"`
|
||||
|
||||
// DryRun configuration
|
||||
// +optional
|
||||
DryRunOption DryRunOption `json:"dryRun,omitempty" yaml:"dryRun,omitempty"`
|
||||
DryRunOption DryRunOption `json:"dryRun,omitempty"`
|
||||
|
||||
// Repository is an optional alternate OCI repository to use for resource bundle reference.
|
||||
// The repository can be overridden per Attestor or Attestation.
|
||||
Repository string `json:"repository,omitempty" yaml:"repository,omitempty"`
|
||||
Repository string `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
// DryRunOption is a configuration for dryrun.
|
||||
|
@ -487,28 +713,21 @@ type Manifests struct {
|
|||
// which provides robust matching against changes by defaults and other admission controllers.
|
||||
// Dryrun requires additional permissions. See config/dryrun/dryrun_rbac.yaml
|
||||
type DryRunOption struct {
|
||||
Enable bool `json:"enable,omitempty" yaml:"enable,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
type ObjectReference struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Enable bool `json:"enable,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
type IgnoreFieldList []ObjectFieldBinding
|
||||
|
||||
type ObjectReferenceList []ObjectReference
|
||||
type ObjectFieldBinding k8smanifest.ObjectFieldBinding
|
||||
|
||||
type ObjectUserBinding struct {
|
||||
Users []string `json:"users,omitempty"`
|
||||
Objects ObjectReferenceList `json:"objects,omitempty"`
|
||||
}
|
||||
// AdmissionOperation can have one of the values CREATE, UPDATE, CONNECT, DELETE, which are used to match a specific action.
|
||||
// +kubebuilder:validation:Enum=CREATE;CONNECT;UPDATE;DELETE
|
||||
type AdmissionOperation admissionv1.Operation
|
||||
|
||||
type ObjectFieldBinding struct {
|
||||
Fields []string `json:"fields,omitempty"`
|
||||
Objects ObjectReferenceList `json:"objects,omitempty"`
|
||||
}
|
||||
const (
|
||||
Create AdmissionOperation = AdmissionOperation(admissionv1.Create)
|
||||
Update AdmissionOperation = AdmissionOperation(admissionv1.Update)
|
||||
Delete AdmissionOperation = AdmissionOperation(admissionv1.Delete)
|
||||
Connect AdmissionOperation = AdmissionOperation(admissionv1.Connect)
|
||||
)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package v1
|
||||
|
||||
const (
|
||||
// PodControllersAnnotation defines the annotation key for Pod-Controllers
|
||||
PodControllersAnnotation = "pod-policies.kyverno.io/autogen-controllers"
|
||||
// LabelAppManagedBy defines the label key for managed-by label
|
||||
LabelAppManagedBy = "app.kubernetes.io/managed-by"
|
||||
AnnotationPolicyCategory = "policies.kyverno.io/category"
|
||||
AnnotationPolicySeverity = "policies.kyverno.io/severity"
|
||||
AnnotationPolicyScored = "policies.kyverno.io/scored"
|
||||
// ValueKyvernoApp defines the kyverno application value
|
||||
ValueKyvernoApp = "kyverno"
|
||||
)
|
|
@ -1,85 +1,135 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/policies.kyverno.io/v1alpha1"
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// ImageVerificationType selects the type of verification algorithm
|
||||
// +kubebuilder:validation:Enum=Cosign;SigstoreBundle;Notary
|
||||
// +kubebuilder:default=Cosign
|
||||
type ImageVerificationType string
|
||||
|
||||
// ImageRegistryCredentialsProvidersType provides the list of credential providers required.
|
||||
type ImageRegistryCredentialsProvidersType v1alpha1.CredentialsProvidersType
|
||||
|
||||
const (
|
||||
Cosign ImageVerificationType = "Cosign"
|
||||
SigstoreBundle ImageVerificationType = "SigstoreBundle"
|
||||
Notary ImageVerificationType = "Notary"
|
||||
|
||||
DEFAULT ImageRegistryCredentialsProvidersType = "default"
|
||||
AWS ImageRegistryCredentialsProvidersType = "amazon"
|
||||
ACR ImageRegistryCredentialsProvidersType = "azure"
|
||||
GCP ImageRegistryCredentialsProvidersType = "google"
|
||||
GHCR ImageRegistryCredentialsProvidersType = "github"
|
||||
)
|
||||
|
||||
var signatureAlgorithmMap = map[string]bool{
|
||||
"": true,
|
||||
"sha224": true,
|
||||
"sha256": true,
|
||||
"sha384": true,
|
||||
"sha512": true,
|
||||
}
|
||||
|
||||
// ImageVerification validates that images that match the specified pattern
|
||||
// are signed with the supplied public key. Once the image is verified it is
|
||||
// mutated to include the SHA digest retrieved during the registration.
|
||||
type ImageVerification struct {
|
||||
// Image is the image name consisting of the registry address, repository, image, and tag.
|
||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// Allowed values are Audit or Enforce.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Audit;Enforce
|
||||
FailureAction *ValidationFailureAction `json:"failureAction,omitempty"`
|
||||
|
||||
// Type specifies the method of signature validation. The allowed options
|
||||
// are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||
// +kubebuilder:validation:Optional
|
||||
Type ImageVerificationType `json:"type,omitempty"`
|
||||
|
||||
// Deprecated. Use ImageReferences instead.
|
||||
// +kubebuilder:validation:Optional
|
||||
Image string `json:"image,omitempty" yaml:"image,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// ImageReferences is a list of matching image reference patterns. At least one pattern in the
|
||||
// list must match the image for the rule to apply. Each image reference consists of a registry
|
||||
// address (defaults to docker.io), repository, image, and tag (defaults to latest).
|
||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// +kubebuilder:validation:Optional
|
||||
ImageReferences []string `json:"imageReferences,omitempty" yaml:"imageReferences,omitempty"`
|
||||
ImageReferences []string `json:"imageReferences,omitempty"`
|
||||
|
||||
// SkipImageReferences is a list of matching image reference patterns that should be skipped.
|
||||
// At least one pattern in the list must match the image for the rule to be skipped. Each image reference
|
||||
// consists of a registry address (defaults to docker.io), repository, image, and tag (defaults to latest).
|
||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// +kubebuilder:validation:Optional
|
||||
SkipImageReferences []string `json:"skipImageReferences,omitempty"`
|
||||
|
||||
// Key is the PEM encoded public key that the image or attestation is signed with.
|
||||
// Deprecated. Use StaticKeyAttestor instead.
|
||||
Key string `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
|
||||
// Roots is the PEM encoded Root certificate chain used for keyless signing
|
||||
// Deprecated. Use KeylessAttestor instead.
|
||||
Roots string `json:"roots,omitempty" yaml:"roots,omitempty"`
|
||||
Roots string `json:"roots,omitempty"`
|
||||
|
||||
// Subject is the identity used for keyless signing, for example an email address
|
||||
// Deprecated. Use KeylessAttestor instead.
|
||||
Subject string `json:"subject,omitempty" yaml:"subject,omitempty"`
|
||||
Subject string `json:"subject,omitempty"`
|
||||
|
||||
// Issuer is the certificate issuer used for keyless signing.
|
||||
// Deprecated. Use KeylessAttestor instead.
|
||||
Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"`
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
|
||||
// AdditionalExtensions are certificate-extensions used for keyless signing.
|
||||
// Deprecated.
|
||||
AdditionalExtensions map[string]string `json:"additionalExtensions,omitempty" yaml:"additionalExtensions,omitempty"`
|
||||
AdditionalExtensions map[string]string `json:"additionalExtensions,omitempty"`
|
||||
|
||||
// Attestors specified the required attestors (i.e. authorities)
|
||||
// +kubebuilder:validation:Optional
|
||||
Attestors []AttestorSet `json:"attestors,omitempty" yaml:"attestors,omitempty"`
|
||||
Attestors []AttestorSet `json:"attestors,omitempty"`
|
||||
|
||||
// Attestations are optional checks for signed in-toto Statements used to verify the image.
|
||||
// See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the
|
||||
// OCI registry and decodes them into a list of Statement declarations.
|
||||
Attestations []Attestation `json:"attestations,omitempty" yaml:"attestations,omitempty"`
|
||||
Attestations []Attestation `json:"attestations,omitempty"`
|
||||
|
||||
// Annotations are used for image verification.
|
||||
// Every specified key-value pair must exist and match in the verified payload.
|
||||
// The payload may contain other key-value pairs.
|
||||
// Deprecated. Use annotations per Attestor instead.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule.
|
||||
// If specified Repository will override the default OCI image repository configured for the installation.
|
||||
// The repository can also be overridden per Attestor or Attestation.
|
||||
Repository string `json:"repository,omitempty" yaml:"repository,omitempty"`
|
||||
Repository string `json:"repository,omitempty"`
|
||||
|
||||
// CosignOCI11 enables the experimental OCI 1.1 behaviour in cosign image verification.
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
CosignOCI11 bool `json:"cosignOCI11,omitempty"`
|
||||
|
||||
// MutateDigest enables replacement of image tags with digests.
|
||||
// Defaults to true.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
MutateDigest bool `json:"mutateDigest" yaml:"mutateDigest"`
|
||||
MutateDigest bool `json:"mutateDigest"`
|
||||
|
||||
// VerifyDigest validates that images have a digest.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
VerifyDigest bool `json:"verifyDigest" yaml:"verifyDigest"`
|
||||
VerifyDigest bool `json:"verifyDigest"`
|
||||
|
||||
// Validation checks conditions across multiple image
|
||||
// verification attestations or context entries
|
||||
Validation ValidateImageVerification `json:"validate,omitempty"`
|
||||
|
||||
// Required validates that images are verified i.e. have matched passed a signature or attestation check.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
Required bool `json:"required" yaml:"required"`
|
||||
Required bool `json:"required"`
|
||||
|
||||
// ImageRegistryCredentials provides credentials that will be used for authentication with registry.
|
||||
// +kubebuilder:validation:Optional
|
||||
ImageRegistryCredentials *ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty"`
|
||||
|
||||
// UseCache enables caching of image verify responses for this rule.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
UseCache bool `json:"useCache"`
|
||||
}
|
||||
|
||||
type AttestorSet struct {
|
||||
|
@ -88,40 +138,44 @@ type AttestorSet struct {
|
|||
// value N, then N must be less than or equal to the size of entries, and at least N entries must match.
|
||||
// +kubebuilder:validation:Optional
|
||||
// +kubebuilder:validation:Minimum:=1
|
||||
Count *int `json:"count,omitempty" yaml:"count,omitempty"`
|
||||
Count *int `json:"count,omitempty"`
|
||||
|
||||
// Entries contains the available attestors. An attestor can be a static key,
|
||||
// attributes for keyless verification, or a nested attestor declaration.
|
||||
// +kubebuilder:validation:Optional
|
||||
Entries []Attestor `json:"entries,omitempty" yaml:"entries,omitempty"`
|
||||
Entries []Attestor `json:"entries,omitempty"`
|
||||
}
|
||||
|
||||
type Attestor struct {
|
||||
// Keys specifies one or more public keys
|
||||
// Keys specifies one or more public keys.
|
||||
// +kubebuilder:validation:Optional
|
||||
Keys *StaticKeyAttestor `json:"keys,omitempty" yaml:"keys,omitempty"`
|
||||
Keys *StaticKeyAttestor `json:"keys,omitempty"`
|
||||
|
||||
// Certificates specifies one or more certificates
|
||||
// Certificates specifies one or more certificates.
|
||||
// +kubebuilder:validation:Optional
|
||||
Certificates *CertificateAttestor `json:"certificates,omitempty" yaml:"certificates,omitempty"`
|
||||
Certificates *CertificateAttestor `json:"certificates,omitempty"`
|
||||
|
||||
// Keyless is a set of attribute used to verify a Sigstore keyless attestor.
|
||||
// See https://github.com/sigstore/cosign/blob/main/KEYLESS.md.
|
||||
// +kubebuilder:validation:Optional
|
||||
Keyless *KeylessAttestor `json:"keyless,omitempty" yaml:"keyless,omitempty"`
|
||||
Keyless *KeylessAttestor `json:"keyless,omitempty"`
|
||||
|
||||
// Attestor is a nested AttestorSet used to specify a more complex set of match authorities
|
||||
// Attestor is a nested set of Attestor used to specify a more complex set of match authorities.
|
||||
// +kubebuilder:validation:Optional
|
||||
Attestor *apiextv1.JSON `json:"attestor,omitempty" yaml:"attestor,omitempty"`
|
||||
Attestor *apiextv1.JSON `json:"attestor,omitempty"`
|
||||
|
||||
// Annotations are used for image verification.
|
||||
// Every specified key-value pair must exist and match in the verified payload.
|
||||
// The payload may contain other key-value pairs.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule.
|
||||
// If specified Repository will override other OCI image repository locations for this Attestor.
|
||||
Repository string `json:"repository,omitempty" yaml:"repository,omitempty"`
|
||||
Repository string `json:"repository,omitempty"`
|
||||
|
||||
// Specify signature algorithm for public keys. Supported values are sha224, sha256, sha384 and sha512.
|
||||
// +kubebuilder:default=sha256
|
||||
SignatureAlgorithm string `json:"signatureAlgorithm,omitempty"`
|
||||
}
|
||||
|
||||
type StaticKeyAttestor struct {
|
||||
|
@ -133,284 +187,177 @@ type StaticKeyAttestor struct {
|
|||
// verification, (see https://github.com/sigstore/cosign/blob/main/KMS.md#kubernetes-secret).
|
||||
// When multiple keys are specified each key is processed as a separate staticKey entry
|
||||
// (.attestors[*].entries.keys) within the set of attestors and the count is applied across the keys.
|
||||
PublicKeys string `json:"publicKeys,omitempty" yaml:"publicKeys,omitempty"`
|
||||
PublicKeys string `json:"publicKeys,omitempty"`
|
||||
|
||||
// Specify signature algorithm for public keys. Supported values are sha256 and sha512
|
||||
// Deprecated. Use attestor.signatureAlgorithm instead.
|
||||
// +kubebuilder:default=sha256
|
||||
SignatureAlgorithm string `json:"signatureAlgorithm,omitempty" yaml:"signatureAlgorithm,omitempty"`
|
||||
SignatureAlgorithm string `json:"signatureAlgorithm,omitempty"`
|
||||
|
||||
// KMS provides the URI to the public key stored in a Key Management System. See:
|
||||
// https://github.com/sigstore/cosign/blob/main/KMS.md
|
||||
KMS string `json:"kms,omitempty" yaml:"kms,omitempty"`
|
||||
KMS string `json:"kms,omitempty"`
|
||||
|
||||
// Reference to a Secret resource that contains a public key
|
||||
Secret *SecretReference `json:"secret,omitempty" yaml:"secret,omitempty"`
|
||||
Secret *SecretReference `json:"secret,omitempty"`
|
||||
|
||||
// Rekor provides configuration for the Rekor transparency log service. If the value is nil,
|
||||
// Rekor is not checked. If an empty object is provided the public instance of
|
||||
// Rekor (https://rekor.sigstore.dev) is used.
|
||||
// Rekor provides configuration for the Rekor transparency log service. If an empty object
|
||||
// is provided the public instance of Rekor (https://rekor.sigstore.dev) is used.
|
||||
// +kubebuilder:validation:Optional
|
||||
Rekor *CTLog `json:"rekor,omitempty" yaml:"rekor,omitempty"`
|
||||
Rekor *Rekor `json:"rekor,omitempty"`
|
||||
|
||||
// CTLog (certificate timestamp log) provides a configuration for validation of Signed Certificate
|
||||
// Timestamps (SCTs). If the value is unset, the default behavior by Cosign is used.
|
||||
// +kubebuilder:validation:Optional
|
||||
CTLog *CTLog `json:"ctlog,omitempty"`
|
||||
}
|
||||
|
||||
type SecretReference struct {
|
||||
// Name of the secret. The provided secret must contain a key named cosign.pub.
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace name where the Secret exists.
|
||||
Namespace string `json:"namespace" yaml:"namespace"`
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
type CertificateAttestor struct {
|
||||
// Certificate is an optional PEM encoded public certificate.
|
||||
// Cert is an optional PEM-encoded public certificate.
|
||||
// +kubebuilder:validation:Optional
|
||||
Certificate string `json:"cert,omitempty" yaml:"cert,omitempty"`
|
||||
Certificate string `json:"cert,omitempty"`
|
||||
|
||||
// CertificateChain is an optional PEM encoded set of certificates used to verify
|
||||
// CertChain is an optional PEM encoded set of certificates used to verify.
|
||||
// +kubebuilder:validation:Optional
|
||||
CertificateChain string `json:"certChain,omitempty" yaml:"certChain,omitempty"`
|
||||
CertificateChain string `json:"certChain,omitempty"`
|
||||
|
||||
// Rekor provides configuration for the Rekor transparency log service. If the value is nil,
|
||||
// Rekor is not checked. If an empty object is provided the public instance of
|
||||
// Rekor (https://rekor.sigstore.dev) is used.
|
||||
// Rekor provides configuration for the Rekor transparency log service. If an empty object
|
||||
// is provided the public instance of Rekor (https://rekor.sigstore.dev) is used.
|
||||
// +kubebuilder:validation:Optional
|
||||
Rekor *CTLog `json:"rekor,omitempty" yaml:"rekor,omitempty"`
|
||||
Rekor *Rekor `json:"rekor,omitempty"`
|
||||
|
||||
// CTLog (certificate timestamp log) provides a configuration for validation of Signed Certificate
|
||||
// Timestamps (SCTs). If the value is unset, the default behavior by Cosign is used.
|
||||
// +kubebuilder:validation:Optional
|
||||
CTLog *CTLog `json:"ctlog,omitempty"`
|
||||
}
|
||||
|
||||
type KeylessAttestor struct {
|
||||
// Rekor provides configuration for the Rekor transparency log service. If the value is nil,
|
||||
// Rekor is not checked and a root certificate chain is expected instead. If an empty object
|
||||
// Rekor provides configuration for the Rekor transparency log service. If an empty object
|
||||
// is provided the public instance of Rekor (https://rekor.sigstore.dev) is used.
|
||||
// +kubebuilder:validation:Optional
|
||||
Rekor *CTLog `json:"rekor,omitempty" yaml:"rekor,omitempty"`
|
||||
Rekor *Rekor `json:"rekor,omitempty"`
|
||||
|
||||
// CTLog (certificate timestamp log) provides a configuration for validation of Signed Certificate
|
||||
// Timestamps (SCTs). If the value is unset, the default behavior by Cosign is used.
|
||||
// +kubebuilder:validation:Optional
|
||||
CTLog *CTLog `json:"ctlog,omitempty"`
|
||||
|
||||
// Issuer is the certificate issuer used for keyless signing.
|
||||
// +kubebuilder:validation:Optional
|
||||
Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"`
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
|
||||
// Subject is the verified identity used for keyless signing, for example the email address
|
||||
// IssuerRegExp is the regular expression to match certificate issuer used for keyless signing.
|
||||
// +kubebuilder:validation:Optional
|
||||
Subject string `json:"subject,omitempty" yaml:"subject,omitempty"`
|
||||
IssuerRegExp string `json:"issuerRegExp,omitempty"`
|
||||
|
||||
// Subject is the verified identity used for keyless signing, for example the email address.
|
||||
// +kubebuilder:validation:Optional
|
||||
Subject string `json:"subject,omitempty"`
|
||||
|
||||
// SubjectRegExp is the regular expression to match identity used for keyless signing, for example the email address.
|
||||
// +kubebuilder:validation:Optional
|
||||
SubjectRegExp string `json:"subjectRegExp,omitempty"`
|
||||
|
||||
// Roots is an optional set of PEM encoded trusted root certificates.
|
||||
// If not provided, the system roots are used.
|
||||
// +kubebuilder:validation:Optional
|
||||
Roots string `json:"roots,omitempty" yaml:"roots,omitempty"`
|
||||
Roots string `json:"roots,omitempty"`
|
||||
|
||||
// AdditionalExtensions are certificate-extensions used for keyless signing.
|
||||
// +kubebuilder:validation:Optional
|
||||
AdditionalExtensions map[string]string `json:"additionalExtensions,omitempty" yaml:"additionalExtensions,omitempty"`
|
||||
AdditionalExtensions map[string]string `json:"additionalExtensions,omitempty"`
|
||||
}
|
||||
|
||||
type Rekor struct {
|
||||
// URL is the address of the transparency log. Defaults to the public Rekor log instance https://rekor.sigstore.dev.
|
||||
// +kubebuilder:validation:Optional
|
||||
// +kubebuilder:Default:=https://rekor.sigstore.dev
|
||||
URL string `json:"url"`
|
||||
|
||||
// RekorPubKey is an optional PEM-encoded public key to use for a custom Rekor.
|
||||
// If set, this will be used to validate transparency log signatures from a custom Rekor.
|
||||
// +kubebuilder:validation:Optional
|
||||
RekorPubKey string `json:"pubkey,omitempty"`
|
||||
|
||||
// IgnoreTlog skips transparency log verification.
|
||||
// +kubebuilder:validation:Optional
|
||||
IgnoreTlog bool `json:"ignoreTlog,omitempty"`
|
||||
}
|
||||
|
||||
type CTLog struct {
|
||||
// URL is the address of the transparency log. Defaults to the public log https://rekor.sigstore.dev.
|
||||
// +kubebuilder:validation:Required
|
||||
// +kubebuilder:Default:=https://rekor.sigstore.dev
|
||||
URL string `json:"url" yaml:"url"`
|
||||
// IgnoreSCT defines whether to use the Signed Certificate Timestamp (SCT) log to check for a certificate
|
||||
// timestamp. Default is false. Set to true if this was opted out during signing.
|
||||
// +kubebuilder:validation:Optional
|
||||
IgnoreSCT bool `json:"ignoreSCT,omitempty"`
|
||||
|
||||
// PubKey, if set, is used to validate SCTs against a custom source.
|
||||
// +kubebuilder:validation:Optional
|
||||
CTLogPubKey string `json:"pubkey,omitempty"`
|
||||
|
||||
// TSACertChain, if set, is the PEM-encoded certificate chain file for the RFC3161 timestamp authority. Must
|
||||
// contain the root CA certificate. Optionally may contain intermediate CA certificates, and
|
||||
// may contain the leaf TSA certificate if not present in the timestamurce.
|
||||
// +kubebuilder:validation:Optional
|
||||
TSACertChain string `json:"tsaCertChain,omitempty"`
|
||||
}
|
||||
|
||||
// Attestation are checks for signed in-toto Statements that are used to verify the image.
|
||||
// See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the
|
||||
// OCI registry and decodes them into a list of Statements.
|
||||
type Attestation struct {
|
||||
// PredicateType defines the type of Predicate contained within the Statement.
|
||||
// +kubebuilder:validation:Required
|
||||
PredicateType string `json:"predicateType" yaml:"predicateType"`
|
||||
// Name is the variable name.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Attestors specify the required attestors (i.e. authorities)
|
||||
// Deprecated in favour of 'Type', to be removed soon
|
||||
// +kubebuilder:validation:Optional
|
||||
Attestors []AttestorSet `json:"attestors" yaml:"attestors"`
|
||||
PredicateType string `json:"predicateType"`
|
||||
|
||||
// Type defines the type of attestation contained within the Statement.
|
||||
// +kubebuilder:validation:Optional
|
||||
Type string `json:"type"`
|
||||
|
||||
// Attestors specify the required attestors (i.e. authorities).
|
||||
// +kubebuilder:validation:Optional
|
||||
Attestors []AttestorSet `json:"attestors"`
|
||||
|
||||
// Conditions are used to verify attributes within a Predicate. If no Conditions are specified
|
||||
// the attestation check is satisfied as long there are predicates that match the predicate type.
|
||||
// +kubebuilder:validation:Optional
|
||||
Conditions []AnyAllConditions `json:"conditions,omitempty" yaml:"conditions,omitempty"`
|
||||
Conditions []AnyAllConditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// Validate implements programmatic validation
|
||||
func (iv *ImageVerification) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
copy := iv.Convert()
|
||||
type ImageRegistryCredentials struct {
|
||||
// AllowInsecureRegistry allows insecure access to a registry.
|
||||
// +kubebuilder:validation:Optional
|
||||
AllowInsecureRegistry bool `json:"allowInsecureRegistry,omitempty"`
|
||||
|
||||
if len(copy.ImageReferences) == 0 {
|
||||
errs = append(errs, field.Invalid(path, iv, "An image reference is required"))
|
||||
}
|
||||
// Providers specifies a list of OCI Registry names, whose authentication providers are provided.
|
||||
// It can be of one of these values: default,google,azure,amazon,github.
|
||||
// +kubebuilder:validation:Optional
|
||||
Providers []ImageRegistryCredentialsProvidersType `json:"providers,omitempty"`
|
||||
|
||||
asPath := path.Child("attestations")
|
||||
for i, attestation := range copy.Attestations {
|
||||
attestationErrors := attestation.Validate(asPath.Index(i))
|
||||
errs = append(errs, attestationErrors...)
|
||||
}
|
||||
|
||||
attestorsPath := path.Child("attestors")
|
||||
for i, as := range copy.Attestors {
|
||||
attestorErrors := as.Validate(attestorsPath.Index(i))
|
||||
errs = append(errs, attestorErrors...)
|
||||
}
|
||||
|
||||
return errs
|
||||
// Secrets specifies a list of secrets that are provided for credentials.
|
||||
// Secrets must live in the Kyverno namespace.
|
||||
// +kubebuilder:validation:Optional
|
||||
Secrets []string `json:"secrets,omitempty"`
|
||||
}
|
||||
|
||||
func (a *Attestation) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if len(a.Attestors) == 0 {
|
||||
return
|
||||
}
|
||||
// ValidateImageVerification checks conditions across multiple image
|
||||
// verification attestations or context entries
|
||||
type ValidateImageVerification struct {
|
||||
// Message specifies a custom message to be displayed on failure.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
attestorsPath := path.Child("attestors")
|
||||
for i, as := range a.Attestors {
|
||||
attestorErrors := as.Validate(attestorsPath.Index(i))
|
||||
errs = append(errs, attestorErrors...)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func (as *AttestorSet) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
return validateAttestorSet(as, path)
|
||||
}
|
||||
|
||||
func validateAttestorSet(as *AttestorSet, path *field.Path) (errs field.ErrorList) {
|
||||
if as.Count != nil {
|
||||
if *as.Count > len(as.Entries) {
|
||||
errs = append(errs, field.Invalid(path, as, "Count cannot exceed length of entries"))
|
||||
}
|
||||
}
|
||||
|
||||
if len(as.Entries) == 0 {
|
||||
errs = append(errs, field.Invalid(path, as, "An entry is required"))
|
||||
}
|
||||
|
||||
entriesPath := path.Child("entries")
|
||||
for i, e := range as.Entries {
|
||||
attestorErrors := e.Validate(entriesPath.Index(i))
|
||||
errs = append(errs, attestorErrors...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func (a *Attestor) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if (a.Keys != nil && (a.Certificates != nil || a.Keyless != nil || a.Attestor != nil)) ||
|
||||
(a.Certificates != nil && (a.Keys != nil || a.Keyless != nil || a.Attestor != nil)) ||
|
||||
(a.Keyless != nil && (a.Certificates != nil || a.Keys != nil || a.Attestor != nil)) ||
|
||||
(a.Attestor != nil && (a.Certificates != nil || a.Keys != nil || a.Keyless != nil)) ||
|
||||
(a.Keys == nil && a.Certificates == nil && a.Keyless == nil && a.Attestor == nil) {
|
||||
errs = append(errs, field.Invalid(path, a, "keys, certificates, keyless, or a nested attestor is required"))
|
||||
}
|
||||
|
||||
if a.Keys != nil {
|
||||
staticKeyPath := path.Child("keys")
|
||||
staticKeyErrors := a.Keys.Validate(staticKeyPath)
|
||||
errs = append(errs, staticKeyErrors...)
|
||||
}
|
||||
|
||||
if a.Certificates != nil {
|
||||
certificatesPath := path.Child("certificates")
|
||||
certificatesErrors := a.Certificates.Validate(certificatesPath)
|
||||
errs = append(errs, certificatesErrors...)
|
||||
}
|
||||
|
||||
if a.Keyless != nil {
|
||||
keylessPath := path.Child("keyless")
|
||||
keylessErrors := a.Keyless.Validate(keylessPath)
|
||||
errs = append(errs, keylessErrors...)
|
||||
}
|
||||
|
||||
if a.Attestor != nil {
|
||||
attestorPath := path.Child("attestor")
|
||||
attestorSet, err := AttestorSetUnmarshal(a.Attestor)
|
||||
if err != nil {
|
||||
fieldErr := field.Invalid(attestorPath, a.Attestor, err.Error())
|
||||
errs = append(errs, fieldErr)
|
||||
} else {
|
||||
attestorErrors := validateAttestorSet(attestorSet, attestorPath)
|
||||
errs = append(errs, attestorErrors...)
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func AttestorSetUnmarshal(o *apiextv1.JSON) (*AttestorSet, error) {
|
||||
var as AttestorSet
|
||||
if err := json.Unmarshal(o.Raw, &as); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal attestor set %s: %w", string(o.Raw), err)
|
||||
}
|
||||
|
||||
return &as, nil
|
||||
}
|
||||
|
||||
func (ska *StaticKeyAttestor) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if ska.PublicKeys == "" && ska.KMS == "" && ska.Secret == nil {
|
||||
errs = append(errs, field.Invalid(path, ska, "A public key, kms key or secret is required"))
|
||||
}
|
||||
if ska.PublicKeys != "" && ska.SignatureAlgorithm != "" && ska.SignatureAlgorithm != "sha256" && ska.SignatureAlgorithm != "sha512" {
|
||||
errs = append(errs, field.Invalid(path, ska, "Invalid signature algorithm provided"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func (ca *CertificateAttestor) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if ca.Certificate == "" && ca.CertificateChain == "" {
|
||||
errs = append(errs, field.Invalid(path, ca, "cert or certChain required"))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func (ka *KeylessAttestor) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if ka.Rekor == nil && ka.Roots == "" {
|
||||
errs = append(errs, field.Invalid(path, ka, "Either Rekor URL or roots are required"))
|
||||
}
|
||||
|
||||
if ka.Rekor != nil && ka.Rekor.URL == "" {
|
||||
errs = append(errs, field.Invalid(path, ka, "An URL is required"))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func (iv *ImageVerification) Convert() *ImageVerification {
|
||||
if iv.Image == "" && iv.Key == "" && iv.Issuer == "" {
|
||||
return iv
|
||||
}
|
||||
|
||||
copy := iv.DeepCopy()
|
||||
copy.Image = ""
|
||||
copy.Issuer = ""
|
||||
copy.Subject = ""
|
||||
copy.Roots = ""
|
||||
|
||||
if iv.Image != "" {
|
||||
copy.ImageReferences = append(copy.ImageReferences, iv.Image)
|
||||
}
|
||||
|
||||
attestorSet := AttestorSet{}
|
||||
if len(iv.Annotations) > 0 || iv.Key != "" || iv.Issuer != "" {
|
||||
attestor := Attestor{
|
||||
Annotations: iv.Annotations,
|
||||
}
|
||||
|
||||
if iv.Key != "" {
|
||||
attestor.Keys = &StaticKeyAttestor{
|
||||
PublicKeys: iv.Key,
|
||||
}
|
||||
} else if iv.Issuer != "" {
|
||||
attestor.Keyless = &KeylessAttestor{
|
||||
Issuer: iv.Issuer,
|
||||
Subject: iv.Subject,
|
||||
Roots: iv.Roots,
|
||||
}
|
||||
}
|
||||
|
||||
attestorSet.Entries = append(attestorSet.Entries, attestor)
|
||||
if len(iv.Attestations) > 0 {
|
||||
for i := range iv.Attestations {
|
||||
copy.Attestations[i].Attestors = append(copy.Attestations[i].Attestors, attestorSet)
|
||||
}
|
||||
} else {
|
||||
copy.Attestors = append(copy.Attestors, attestorSet)
|
||||
}
|
||||
}
|
||||
|
||||
copy.Attestations = iv.Attestations
|
||||
return copy
|
||||
// Deny defines conditions used to pass or fail a validation rule.
|
||||
// +optional
|
||||
Deny *Deny `json:"deny,omitempty"`
|
||||
}
|
||||
|
|
|
@ -2,25 +2,26 @@ package v1
|
|||
|
||||
// MatchResources is used to specify resource and admission review request data for
|
||||
// which a policy rule is applicable.
|
||||
// +kubebuilder:not:={required:{any,all}}
|
||||
type MatchResources struct {
|
||||
// Any allows specifying resources which will be ORed
|
||||
// +optional
|
||||
Any ResourceFilters `json:"any,omitempty" yaml:"any,omitempty"`
|
||||
Any ResourceFilters `json:"any,omitempty"`
|
||||
|
||||
// All allows specifying resources which will be ANDed
|
||||
// +optional
|
||||
All ResourceFilters `json:"all,omitempty" yaml:"all,omitempty"`
|
||||
All ResourceFilters `json:"all,omitempty"`
|
||||
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
// Specifying UserInfo directly under match is being deprecated.
|
||||
// Please specify under "any" or "all" instead.
|
||||
// +optional
|
||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||
UserInfo `json:",omitempty"`
|
||||
|
||||
// ResourceDescription contains information about the resource being created or modified.
|
||||
// Requires at least one tag to be specified when under MatchResources.
|
||||
// Specifying ResourceDescription directly under match is being deprecated.
|
||||
// Please specify under "any" or "all" instead.
|
||||
// +optional
|
||||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
ResourceDescription `json:"resources,omitempty"`
|
||||
}
|
||||
|
|
|
@ -8,12 +8,7 @@ import (
|
|||
// +kubebuilder:object:generate=false
|
||||
type PolicyInterface interface {
|
||||
metav1.Object
|
||||
HasAutoGenAnnotation() bool
|
||||
IsNamespaced() bool
|
||||
GetSpec() *Spec
|
||||
GetStatus() *PolicyStatus
|
||||
GetKind() string
|
||||
SetKind(string)
|
||||
GetAPIVersion() string
|
||||
SetAPIVersion(string)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -16,39 +17,68 @@ const (
|
|||
PolicyReasonFailed = "Failed"
|
||||
)
|
||||
|
||||
// PolicyStatus mostly contains runtime information related to policy execution.
|
||||
// Deprecated. Policy metrics are now available via the "/metrics" endpoint.
|
||||
// See: https://kyverno.io/docs/monitoring-kyverno-with-prometheus-metrics/
|
||||
type PolicyStatus struct {
|
||||
// Ready indicates if the policy is ready to serve the admission request.
|
||||
// Deprecated in favor of Conditions
|
||||
Ready bool `json:"ready" yaml:"ready"`
|
||||
// Conditions is a list of conditions that apply to the policy
|
||||
Ready *bool `json:"ready,omitempty"`
|
||||
// +optional
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// Autogen contains autogen status information
|
||||
// +optional
|
||||
Autogen AutogenStatus `json:"autogen" yaml:"autogen"`
|
||||
// RuleCount describes total number of rules in a policy
|
||||
Autogen AutogenStatus `json:"autogen"`
|
||||
// +optional
|
||||
RuleCount RuleCountStatus `json:"rulecount" yaml:"rulecount"`
|
||||
RuleCount RuleCountStatus `json:"rulecount"`
|
||||
// ValidatingAdmissionPolicy contains status information
|
||||
// +optional
|
||||
ValidatingAdmissionPolicy ValidatingAdmissionPolicyStatus `json:"validatingadmissionpolicy"`
|
||||
}
|
||||
|
||||
// RuleCountStatus contains four variables which describes counts for
|
||||
// validate, generate, mutate and verify images rules
|
||||
type RuleCountStatus struct {
|
||||
// Count for validate rules in policy
|
||||
Validate int `json:"validate" yaml:"validate"`
|
||||
Validate int `json:"validate"`
|
||||
// Count for generate rules in policy
|
||||
Generate int `json:"generate" yaml:"generate"`
|
||||
Generate int `json:"generate"`
|
||||
// Count for mutate rules in policy
|
||||
Mutate int `json:"mutate" yaml:"mutate"`
|
||||
Mutate int `json:"mutate"`
|
||||
// Count for verify image rules in policy
|
||||
VerifyImages int `json:"verifyimages" yaml:"verifyimages"`
|
||||
VerifyImages int `json:"verifyimages"`
|
||||
}
|
||||
|
||||
func (status *PolicyStatus) SetReady(ready bool, message string) {
|
||||
condition := metav1.Condition{
|
||||
Type: PolicyConditionReady,
|
||||
Message: message,
|
||||
}
|
||||
if ready {
|
||||
condition.Status = metav1.ConditionTrue
|
||||
condition.Reason = PolicyReasonSucceeded
|
||||
} else {
|
||||
condition.Status = metav1.ConditionFalse
|
||||
condition.Reason = PolicyReasonFailed
|
||||
}
|
||||
status.Ready = nil
|
||||
meta.SetStatusCondition(&status.Conditions, condition)
|
||||
}
|
||||
|
||||
// IsReady indicates if the policy is ready to serve the admission request
|
||||
func (status *PolicyStatus) IsReady() bool {
|
||||
condition := meta.FindStatusCondition(status.Conditions, PolicyConditionReady)
|
||||
return condition != nil && condition.Status == metav1.ConditionTrue
|
||||
}
|
||||
|
||||
// AutogenStatus contains autogen status information.
|
||||
type AutogenStatus struct {
|
||||
// Rules is a list of Rule instances. It contains auto generated rules added for pod controllers
|
||||
Rules []Rule `json:"rules,omitempty" yaml:"rules,omitempty"`
|
||||
Rules []Rule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
// ValidatingAdmissionPolicy contains status information
|
||||
type ValidatingAdmissionPolicyStatus struct {
|
||||
// Generated indicates whether a validating admission policy is generated from the policy or not
|
||||
Generated bool `json:"generated"`
|
||||
// Message is a human readable message indicating details about the generation of validating admission policy
|
||||
// It is an empty string when validating admission policy is successfully generated.
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -10,71 +8,31 @@ import (
|
|||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Background",type=boolean,JSONPath=".spec.background"
|
||||
// +kubebuilder:printcolumn:name="Validate Action",type=string,JSONPath=".spec.validationFailureAction"
|
||||
// +kubebuilder:printcolumn:name="Failure Policy",type=string,JSONPath=".spec.failurePolicy",priority=1
|
||||
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="Validate",type=integer,JSONPath=`.status.rulecount.validate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="Mutate",type=integer,JSONPath=`.status.rulecount.mutate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="Generate",type=integer,JSONPath=`.status.rulecount.generate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="Verifyimages",type=integer,JSONPath=`.status.rulecount.verifyimages`,priority=1
|
||||
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
|
||||
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1
|
||||
// +kubebuilder:printcolumn:name="VALIDATE",type=integer,JSONPath=`.status.rulecount.validate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MUTATE",type=integer,JSONPath=`.status.rulecount.mutate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="GENERATE",type=integer,JSONPath=`.status.rulecount.generate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="VERIFY IMAGES",type=integer,JSONPath=`.status.rulecount.verifyimages`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MESSAGE",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].message`
|
||||
// +kubebuilder:resource:shortName=pol,categories=kyverno
|
||||
// +kubebuilder:storageversion
|
||||
|
||||
// Policy declares validation, mutation, and generation behaviors for matching resources.
|
||||
// See: https://kyverno.io/docs/writing-policies/ for more information.
|
||||
type Policy struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
metav1.TypeMeta `json:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines policy behaviors and contains one or more rules.
|
||||
Spec Spec `json:"spec" yaml:"spec"`
|
||||
Spec Spec `json:"spec"`
|
||||
|
||||
// Status contains policy runtime information.
|
||||
// +optional
|
||||
// Deprecated. Policy metrics are available via the metrics endpoint
|
||||
Status PolicyStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
||||
}
|
||||
|
||||
// HasAutoGenAnnotation checks if a policy has auto-gen annotation
|
||||
func (p *Policy) HasAutoGenAnnotation() bool {
|
||||
annotations := p.GetAnnotations()
|
||||
val, ok := annotations[PodControllersAnnotation]
|
||||
if ok && strings.ToLower(val) != "none" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasMutateOrValidateOrGenerate checks for rule types
|
||||
func (p *Policy) HasMutateOrValidateOrGenerate() bool {
|
||||
for _, rule := range p.Spec.Rules {
|
||||
if rule.HasMutate() || rule.HasValidate() || rule.HasGenerate() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasMutate checks for mutate rule types
|
||||
func (p *Policy) HasMutate() bool {
|
||||
return p.Spec.HasMutate()
|
||||
}
|
||||
|
||||
// HasValidate checks for validate rule types
|
||||
func (p *Policy) HasValidate() bool {
|
||||
return p.Spec.HasValidate()
|
||||
}
|
||||
|
||||
// HasGenerate checks for generate rule types
|
||||
func (p *Policy) HasGenerate() bool {
|
||||
return p.Spec.HasGenerate()
|
||||
}
|
||||
|
||||
// HasVerifyImages checks for image verification rule types
|
||||
func (p *Policy) HasVerifyImages() bool {
|
||||
return p.Spec.HasVerifyImages()
|
||||
Status PolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetSpec returns the policy spec
|
||||
|
@ -87,36 +45,15 @@ func (p *Policy) GetStatus() *PolicyStatus {
|
|||
return &p.Status
|
||||
}
|
||||
|
||||
// IsNamespaced indicates if the policy is namespace scoped
|
||||
func (p *Policy) IsNamespaced() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *Policy) GetKind() string {
|
||||
return p.Kind
|
||||
}
|
||||
|
||||
func (p *Policy) GetAPIVersion() string {
|
||||
return p.APIVersion
|
||||
}
|
||||
|
||||
func (p *Policy) SetKind(value string) {
|
||||
p.Kind = value
|
||||
}
|
||||
|
||||
func (p *Policy) SetAPIVersion(value string) {
|
||||
p.APIVersion = value
|
||||
}
|
||||
|
||||
func (p *Policy) CreateDeepCopy() PolicyInterface {
|
||||
return p.DeepCopy()
|
||||
return "Policy"
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PolicyList is a list of Policy instances.
|
||||
type PolicyList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []Policy `json:"items" yaml:"items"`
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []Policy `json:"items"`
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/kyverno/policy-reporter-plugins/plugins/kyverno/pkg/crd/api/kyverno"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: kyverno.GroupName, Version: "v1"}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// SchemeBuilder builds the scheme
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ClusterPolicy{},
|
||||
&ClusterPolicyList{},
|
||||
&Policy{},
|
||||
&PolicyList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
|
@ -5,39 +5,40 @@ import (
|
|||
)
|
||||
|
||||
// ResourceDescription contains criteria used to match resources.
|
||||
// +kubebuilder:not:={required:{name,names}}
|
||||
type ResourceDescription struct {
|
||||
// Kinds is a list of resource kinds.
|
||||
// +optional
|
||||
Kinds []string `json:"kinds,omitempty" yaml:"kinds,omitempty"`
|
||||
Kinds []string `json:"kinds,omitempty"`
|
||||
|
||||
// Name is the name of the resource. The name supports wildcard characters
|
||||
// "*" (matches zero or many characters) and "?" (at least one character).
|
||||
// NOTE: "Name" is being deprecated in favor of "Names".
|
||||
// +optional
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Names are the names of the resources. Each name supports wildcard characters
|
||||
// "*" (matches zero or many characters) and "?" (at least one character).
|
||||
// +optional
|
||||
Names []string `json:"names,omitempty" yaml:"names,omitempty"`
|
||||
Names []string `json:"names,omitempty"`
|
||||
|
||||
// Namespaces is a list of namespaces names. Each name supports wildcard characters
|
||||
// "*" (matches zero or many characters) and "?" (at least one character).
|
||||
// +optional
|
||||
Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"`
|
||||
Namespaces []string `json:"namespaces,omitempty"`
|
||||
|
||||
// Annotations is a map of annotations (key-value pairs of type string). Annotation keys
|
||||
// and values support the wildcard characters "*" (matches zero or many characters) and
|
||||
// "?" (matches at least one character).
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Selector is a label selector. Label keys and values in `matchLabels` support the wildcard
|
||||
// characters `*` (matches zero or many characters) and `?` (matches one character).
|
||||
// Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that
|
||||
// using ["*" : "*"] matches any key and value but does not match an empty label set.
|
||||
// +optional
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"`
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// NamespaceSelector is a label selector for the resource namespace. Label keys and values
|
||||
// in `matchLabels` support the wildcard characters `*` (matches zero or many characters)
|
||||
|
@ -45,5 +46,9 @@ type ResourceDescription struct {
|
|||
// ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but
|
||||
// does not match an empty label set.
|
||||
// +optional
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"`
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
|
||||
|
||||
// Operations can contain values ["CREATE, "UPDATE", "CONNECT", "DELETE"], which are used to match a specific action.
|
||||
// +optional
|
||||
Operations []AdmissionOperation `json:"operations,omitempty"`
|
||||
}
|
||||
|
|
|
@ -1,20 +1,51 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type ResourceSpec struct {
|
||||
// APIVersion specifies resource apiVersion.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
// Kind specifies resource kind.
|
||||
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
// Namespace specifies resource namespace.
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// Name specifies the resource name.
|
||||
// +optional
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
// UID specifies the resource uid.
|
||||
// +optional
|
||||
UID types.UID `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
func (s ResourceSpec) GetName() string { return s.Name }
|
||||
func (s ResourceSpec) GetNamespace() string { return s.Namespace }
|
||||
func (s ResourceSpec) GetKind() string { return s.Kind }
|
||||
func (s ResourceSpec) GetAPIVersion() string { return s.APIVersion }
|
||||
type TargetSelector struct {
|
||||
// ResourceSpec contains the target resources to load when mutating existing resources.
|
||||
ResourceSpec `json:",omitempty"`
|
||||
// Selector allows you to select target resources with their labels.
|
||||
// +optional
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
// TargetResourceSpec defines targets for mutating existing resources.
|
||||
type TargetResourceSpec struct {
|
||||
// TargetSelector contains the ResourceSpec and a label selector to support selecting with labels.
|
||||
TargetSelector `json:",omitempty"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []ContextEntry `json:"context,omitempty"`
|
||||
|
||||
// Preconditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements. A direct list
|
||||
// of conditions (without `any` or `all` statements is supported for backwards compatibility but
|
||||
// will be deprecated in the next major release.
|
||||
// See: https://kyverno.io/docs/writing-policies/preconditions/
|
||||
// +optional
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawAnyAllConditions *ConditionsWrapper `json:"preconditions,omitempty"`
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/utils"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
)
|
||||
|
||||
type ImageExtractorConfigs map[string][]ImageExtractorConfig
|
||||
|
@ -12,19 +11,25 @@ type ImageExtractorConfig struct {
|
|||
// Path is the path to the object containing the image field in a custom resource.
|
||||
// It should be slash-separated. Each slash-separated key must be a valid YAML key or a wildcard '*'.
|
||||
// Wildcard keys are expanded in case of arrays or objects.
|
||||
Path string `json:"path" yaml:"path"`
|
||||
Path string `json:"path"`
|
||||
// Value is an optional name of the field within 'path' that points to the image URI.
|
||||
// This is useful when a custom 'key' is also defined.
|
||||
// +optional
|
||||
Value string `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
// Name is the entry the image will be available under 'images.<name>' in the context.
|
||||
// If this field is not defined, image entries will appear under 'images.custom'.
|
||||
// +optional
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
// Key is an optional name of the field within 'path' that will be used to uniquely identify an image.
|
||||
// Note - this field MUST be unique.
|
||||
// +optional
|
||||
Key string `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
// JMESPath is an optional JMESPath expression to apply to the image value.
|
||||
// This is useful when the extracted image begins with a prefix like 'docker://'.
|
||||
// The 'trim_prefix' function may be used to trim the prefix: trim_prefix(@, 'docker://').
|
||||
// Note - Image digest mutation may not be used when applying a JMESPAth to an image.
|
||||
// +optional
|
||||
JMESPath string `json:"jmesPath,omitempty"`
|
||||
}
|
||||
|
||||
// Rule defines a validation, mutation, or generation control for matching resources.
|
||||
|
@ -33,28 +38,32 @@ type ImageExtractorConfig struct {
|
|||
type Rule struct {
|
||||
// Name is a label to identify the rule, It must be unique within the policy.
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Name string `json:"name"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []ContextEntry `json:"context,omitempty" yaml:"context,omitempty"`
|
||||
Context []ContextEntry `json:"context,omitempty"`
|
||||
|
||||
// ReportProperties are the additional properties from the rule that will be added to the policy report result
|
||||
// +optional
|
||||
ReportProperties map[string]string `json:"reportProperties,omitempty"`
|
||||
|
||||
// MatchResources defines when this policy rule should be applied. The match
|
||||
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
||||
// and admission review request information like the user name or role.
|
||||
// At least one kind is required.
|
||||
MatchResources MatchResources `json:"match,omitempty" yaml:"match,omitempty"`
|
||||
MatchResources MatchResources `json:"match"`
|
||||
|
||||
// ExcludeResources defines when this policy rule should not be applied. The exclude
|
||||
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
||||
// and admission review request information like the name or role.
|
||||
// +optional
|
||||
ExcludeResources MatchResources `json:"exclude,omitempty" yaml:"exclude,omitempty"`
|
||||
ExcludeResources *MatchResources `json:"exclude,omitempty"`
|
||||
|
||||
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
||||
// This config is only valid for verifyImages rules.
|
||||
// +optional
|
||||
ImageExtractors ImageExtractorConfigs `json:"imageExtractors,omitempty" yaml:"imageExtractors,omitempty"`
|
||||
ImageExtractors ImageExtractorConfigs `json:"imageExtractors,omitempty"`
|
||||
|
||||
// Preconditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements. A direct list
|
||||
|
@ -62,73 +71,50 @@ type Rule struct {
|
|||
// will be deprecated in the next major release.
|
||||
// See: https://kyverno.io/docs/writing-policies/preconditions/
|
||||
// +optional
|
||||
RawAnyAllConditions *apiextv1.JSON `json:"preconditions,omitempty" yaml:"preconditions,omitempty"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawAnyAllConditions *ConditionsWrapper `json:"preconditions,omitempty"`
|
||||
|
||||
// CELPreconditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of CEL conditions. It can only be used with the validate.cel subrule
|
||||
// +optional
|
||||
CELPreconditions []admissionregistrationv1.MatchCondition `json:"celPreconditions,omitempty"`
|
||||
|
||||
// Mutation is used to modify matching resources.
|
||||
// +optional
|
||||
Mutation Mutation `json:"mutate,omitempty" yaml:"mutate,omitempty"`
|
||||
Mutation *Mutation `json:"mutate,omitempty"`
|
||||
|
||||
// Validation is used to validate matching resources.
|
||||
// +optional
|
||||
Validation Validation `json:"validate,omitempty" yaml:"validate,omitempty"`
|
||||
Validation *Validation `json:"validate,omitempty"`
|
||||
|
||||
// Generation is used to create new resources.
|
||||
// +optional
|
||||
Generation Generation `json:"generate,omitempty" yaml:"generate,omitempty"`
|
||||
Generation *Generation `json:"generate,omitempty"`
|
||||
|
||||
// VerifyImages is used to verify image signatures and mutate them to add a digest
|
||||
// +optional
|
||||
VerifyImages []ImageVerification `json:"verifyImages,omitempty" yaml:"verifyImages,omitempty"`
|
||||
VerifyImages []ImageVerification `json:"verifyImages,omitempty"`
|
||||
|
||||
// SkipBackgroundRequests bypasses admission requests that are sent by the background controller.
|
||||
// The default value is set to "true", it must be set to "false" to apply
|
||||
// generate and mutateExisting rules to those requests.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
SkipBackgroundRequests *bool `json:"skipBackgroundRequests,omitempty"`
|
||||
}
|
||||
|
||||
// HasMutate checks for mutate rule
|
||||
func (r *Rule) HasMutate() bool {
|
||||
return !reflect.DeepEqual(r.Mutation, Mutation{})
|
||||
}
|
||||
|
||||
// HasVerifyImages checks for verifyImages rule
|
||||
func (r *Rule) HasVerifyImages() bool {
|
||||
return r.VerifyImages != nil && !reflect.DeepEqual(r.VerifyImages, ImageVerification{})
|
||||
}
|
||||
|
||||
// HasYAMLSignatureVerify checks for validate.manifests rule
|
||||
func (r Rule) HasYAMLSignatureVerify() bool {
|
||||
return r.Validation.Manifests != nil && len(r.Validation.Manifests.Attestors) != 0
|
||||
}
|
||||
|
||||
// HasImagesValidationChecks checks whether the verifyImages rule has validation checks
|
||||
func (r *Rule) HasImagesValidationChecks() bool {
|
||||
for _, v := range r.VerifyImages {
|
||||
if v.VerifyDigest || v.Required {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// HasYAMLSignatureVerify checks for validate rule
|
||||
func (p *ClusterPolicy) HasYAMLSignatureVerify() bool {
|
||||
for _, rule := range p.Spec.Rules {
|
||||
if rule.HasYAMLSignatureVerify() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return r.Mutation != nil && !utils.DeepEqual(*r.Mutation, Mutation{})
|
||||
}
|
||||
|
||||
// HasValidate checks for validate rule
|
||||
func (r *Rule) HasValidate() bool {
|
||||
return !reflect.DeepEqual(r.Validation, Validation{})
|
||||
return r.Validation != nil && !utils.DeepEqual(*r.Validation, Validation{})
|
||||
}
|
||||
|
||||
// HasGenerate checks for generate rule
|
||||
func (r *Rule) HasGenerate() bool {
|
||||
return !reflect.DeepEqual(r.Generation, Generation{})
|
||||
}
|
||||
|
||||
// IsMutateExisting checks if the mutate rule applies to existing resources
|
||||
func (r *Rule) IsMutateExisting() bool {
|
||||
return r.Mutation.Targets != nil
|
||||
return r.Generation != nil && !utils.DeepEqual(*r.Generation, Generation{})
|
||||
}
|
||||
|
|
|
@ -35,72 +35,81 @@ func (a ValidationFailureAction) IsValid() bool {
|
|||
|
||||
type ValidationFailureActionOverride struct {
|
||||
// +kubebuilder:validation:Enum=audit;enforce;Audit;Enforce
|
||||
Action ValidationFailureAction `json:"action,omitempty" yaml:"action,omitempty"`
|
||||
Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"`
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"`
|
||||
Action ValidationFailureAction `json:"action,omitempty"`
|
||||
Namespaces []string `json:"namespaces,omitempty"`
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
|
||||
}
|
||||
|
||||
// Spec contains a list of Rule instances and other policy controls.
|
||||
type Spec struct {
|
||||
// Rules is a list of Rule instances. A Policy contains multiple rules and
|
||||
// each rule can validate, mutate, or generate resources.
|
||||
Rules []Rule `json:"rules,omitempty" yaml:"rules,omitempty"`
|
||||
Rules []Rule `json:"rules,omitempty"`
|
||||
|
||||
// ApplyRules controls how rules in a policy are applied. Rule are processed in
|
||||
// the order of declaration. When set to `One` processing stops after a rule has
|
||||
// been applied i.e. the rule matches and results in a pass, fail, or error. When
|
||||
// set to `All` all rules in the policy are processed. The default is `All`.
|
||||
// +optional
|
||||
ApplyRules *ApplyRulesType `json:"applyRules,omitempty" yaml:"applyRules,omitempty"`
|
||||
ApplyRules *ApplyRulesType `json:"applyRules,omitempty"`
|
||||
|
||||
// FailurePolicy defines how unexpected policy errors and webhook response timeout errors are handled.
|
||||
// Rules within the same policy share the same failure behavior.
|
||||
// This field should not be accessed directly, instead `GetFailurePolicy()` should be used.
|
||||
// Allowed values are Ignore or Fail. Defaults to Fail.
|
||||
// +optional
|
||||
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" yaml:"failurePolicy,omitempty"`
|
||||
// Deprecated, use failurePolicy under the webhookConfiguration instead.
|
||||
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty"`
|
||||
|
||||
// ValidationFailureAction defines if a validation policy rule violation should block
|
||||
// the admission review request (enforce), or allow (audit) the admission review request
|
||||
// and report an error in a policy report. Optional.
|
||||
// Allowed values are audit or enforce. The default value is "Audit".
|
||||
// +optional
|
||||
// Deprecated, use validationFailureAction under the validate rule instead.
|
||||
// +kubebuilder:validation:Enum=audit;enforce;Audit;Enforce
|
||||
// +kubebuilder:default=Audit
|
||||
ValidationFailureAction ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
|
||||
ValidationFailureAction ValidationFailureAction `json:"validationFailureAction,omitempty"`
|
||||
|
||||
// ValidationFailureActionOverrides is a Cluster Policy attribute that specifies ValidationFailureAction
|
||||
// namespace-wise. It overrides ValidationFailureAction for the specified namespaces.
|
||||
// Deprecated, use validationFailureActionOverrides under the validate rule instead.
|
||||
ValidationFailureActionOverrides []ValidationFailureActionOverride `json:"validationFailureActionOverrides,omitempty"`
|
||||
|
||||
// EmitWarning enables API response warnings for mutate policy rules or validate policy rules with validationFailureAction set to Audit.
|
||||
// Enabling this option will extend admission request processing times. The default value is "false".
|
||||
// +optional
|
||||
ValidationFailureActionOverrides []ValidationFailureActionOverride `json:"validationFailureActionOverrides,omitempty" yaml:"validationFailureActionOverrides,omitempty"`
|
||||
// +kubebuilder:default=false
|
||||
EmitWarning *bool `json:"emitWarning,omitempty"`
|
||||
|
||||
// Admission controls if rules are applied during admission.
|
||||
// Optional. Default value is "true".
|
||||
// +optional
|
||||
// +kubebuilder:default=true
|
||||
Admission *bool `json:"admission,omitempty"`
|
||||
|
||||
// Background controls if rules are applied to existing resources during a background scan.
|
||||
// Optional. Default value is "true". The value must be set to "false" if the policy rule
|
||||
// uses variables that are only available in the admission review request (e.g. user name).
|
||||
// +optional
|
||||
// +kubebuilder:default=true
|
||||
Background *bool `json:"background,omitempty" yaml:"background,omitempty"`
|
||||
Background *bool `json:"background,omitempty"`
|
||||
|
||||
// SchemaValidation skips validation checks for policies as well as patched resources.
|
||||
// Optional. The default value is set to "true", it must be set to "false" to disable the validation checks.
|
||||
// Deprecated.
|
||||
SchemaValidation *bool `json:"schemaValidation,omitempty"`
|
||||
|
||||
// Deprecated, use webhookTimeoutSeconds under webhookConfiguration instead.
|
||||
WebhookTimeoutSeconds *int32 `json:"webhookTimeoutSeconds,omitempty"`
|
||||
|
||||
// Deprecated, use mutateExistingOnPolicyUpdate under the mutate rule instead
|
||||
// +optional
|
||||
SchemaValidation *bool `json:"schemaValidation,omitempty" yaml:"schemaValidation,omitempty"`
|
||||
MutateExistingOnPolicyUpdate bool `json:"mutateExistingOnPolicyUpdate,omitempty"`
|
||||
|
||||
// WebhookTimeoutSeconds specifies the maximum time in seconds allowed to apply this policy.
|
||||
// After the configured time expires, the admission request may fail, or may simply ignore the policy results,
|
||||
// based on the failure policy. The default timeout is 10s, the value must be between 1 and 30 seconds.
|
||||
WebhookTimeoutSeconds *int32 `json:"webhookTimeoutSeconds,omitempty" yaml:"webhookTimeoutSeconds,omitempty"`
|
||||
|
||||
// MutateExistingOnPolicyUpdate controls if a mutateExisting policy is applied on policy events.
|
||||
// Default value is "false".
|
||||
// Deprecated, use generateExisting instead
|
||||
// +optional
|
||||
MutateExistingOnPolicyUpdate bool `json:"mutateExistingOnPolicyUpdate,omitempty" yaml:"mutateExistingOnPolicyUpdate,omitempty"`
|
||||
GenerateExistingOnPolicyUpdate *bool `json:"generateExistingOnPolicyUpdate,omitempty"`
|
||||
|
||||
// GenerateExistingOnPolicyUpdate controls whether to trigger generate rule in existing resources
|
||||
// If is set to "true" generate rule will be triggered and applied to existing matched resources.
|
||||
// Deprecated, use generateExisting under the generate rule instead
|
||||
// +optional
|
||||
GenerateExisting bool `json:"generateExisting,omitempty"`
|
||||
|
||||
// UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
// If is set to "true" create & update for generate rules will use apply instead of create/update.
|
||||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
GenerateExistingOnPolicyUpdate bool `json:"generateExistingOnPolicyUpdate,omitempty" yaml:"generateExistingOnPolicyUpdate,omitempty"`
|
||||
UseServerSideApply bool `json:"useServerSideApply,omitempty"`
|
||||
|
||||
// WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
|
||||
// +optional
|
||||
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty"`
|
||||
}
|
||||
|
||||
// HasMutate checks for mutate rule types
|
||||
|
@ -110,7 +119,6 @@ func (s *Spec) HasMutate() bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -121,50 +129,5 @@ func (s *Spec) HasValidate() bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// HasGenerate checks for generate rule types
|
||||
func (s *Spec) HasGenerate() bool {
|
||||
for _, rule := range s.Rules {
|
||||
if rule.HasGenerate() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// HasImagesValidationChecks checks for image verification rules invoked during resource validation
|
||||
func (s *Spec) HasImagesValidationChecks() bool {
|
||||
for _, rule := range s.Rules {
|
||||
if rule.HasImagesValidationChecks() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// HasVerifyImages checks for image verification rules invoked during resource mutation
|
||||
func (s *Spec) HasVerifyImages() bool {
|
||||
for _, rule := range s.Rules {
|
||||
if rule.HasVerifyImages() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// HasYAMLSignatureVerify checks for image verification rules invoked during resource mutation
|
||||
func (s *Spec) HasYAMLSignatureVerify() bool {
|
||||
for _, rule := range s.Rules {
|
||||
if rule.HasYAMLSignatureVerify() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -8,13 +8,19 @@ import (
|
|||
type UserInfo struct {
|
||||
// Roles is the list of namespaced role names for the user.
|
||||
// +optional
|
||||
Roles []string `json:"roles,omitempty" yaml:"roles,omitempty"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
|
||||
// ClusterRoles is the list of cluster-wide role names for the user.
|
||||
// +optional
|
||||
ClusterRoles []string `json:"clusterRoles,omitempty" yaml:"clusterRoles,omitempty"`
|
||||
ClusterRoles []string `json:"clusterRoles,omitempty"`
|
||||
|
||||
// Subjects is the list of subject names like users, user groups, and service accounts.
|
||||
// +optional
|
||||
Subjects []rbacv1.Subject `json:"subjects,omitempty" yaml:"subjects,omitempty"`
|
||||
Subjects []rbacv1.Subject `json:"subjects,omitempty"`
|
||||
}
|
||||
|
||||
func (r UserInfo) IsEmpty() bool {
|
||||
return len(r.Roles) == 0 &&
|
||||
len(r.ClusterRoles) == 0 &&
|
||||
len(r.Subjects) == 0
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package v1
|
||||
|
||||
// ViolatedRule stores the information regarding the rule.
|
||||
type ViolatedRule struct {
|
||||
// Name specifies violated rule name.
|
||||
Name string `json:"name" yaml:"name"`
|
||||
|
||||
// Type specifies violated rule type.
|
||||
Type string `json:"type" yaml:"type"`
|
||||
|
||||
// Message specifies violation message.
|
||||
// +optional
|
||||
Message string `json:"message" yaml:"message"`
|
||||
|
||||
// Status shows the rule response status
|
||||
Status string `json:"status" yaml:"status"`
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
// ForEachValidationWrapper contains a list of ForEach descriptors.
|
||||
// +k8s:deepcopy-gen=false
|
||||
type ForEachValidationWrapper struct {
|
||||
// Item is a descriptor on how to iterate over the list of items.
|
||||
// +optional
|
||||
Items []ForEachValidation `json:"-"`
|
||||
}
|
||||
|
||||
func (in *ForEachValidationWrapper) DeepCopyInto(out *ForEachValidationWrapper) {
|
||||
if err := copier.Copy(out, in); err != nil {
|
||||
panic("deep copy failed")
|
||||
}
|
||||
}
|
||||
|
||||
func (in *ForEachValidationWrapper) DeepCopy() *ForEachValidationWrapper {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ForEachValidationWrapper)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (a *ForEachValidationWrapper) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(a.Items)
|
||||
}
|
||||
|
||||
func (a *ForEachValidationWrapper) UnmarshalJSON(data []byte) error {
|
||||
var res []ForEachValidation
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
a.Items = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForEachMutationWrapper contains a list of ForEach descriptors.
|
||||
// +k8s:deepcopy-gen=false
|
||||
type ForEachMutationWrapper struct {
|
||||
// Item is a descriptor on how to iterate over the list of items.
|
||||
// +optional
|
||||
Items []ForEachMutation `json:"-"`
|
||||
}
|
||||
|
||||
func (in *ForEachMutationWrapper) DeepCopyInto(out *ForEachMutationWrapper) {
|
||||
if err := copier.Copy(out, in); err != nil {
|
||||
panic("deep copy failed")
|
||||
}
|
||||
}
|
||||
|
||||
func (in *ForEachMutationWrapper) DeepCopy() *ForEachMutationWrapper {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ForEachMutationWrapper)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (a *ForEachMutationWrapper) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(a.Items)
|
||||
}
|
||||
|
||||
func (a *ForEachMutationWrapper) UnmarshalJSON(data []byte) error {
|
||||
var res []ForEachMutation
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
a.Items = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConditionsWrapper contains either the deprecated list of Conditions or the new AnyAll Conditions.
|
||||
// +k8s:deepcopy-gen=false
|
||||
type ConditionsWrapper struct {
|
||||
// Conditions is a list of conditions that must be satisfied for the rule to be applied.
|
||||
// +optional
|
||||
Conditions any `json:"-"`
|
||||
}
|
||||
|
||||
func (in *ConditionsWrapper) DeepCopyInto(out *ConditionsWrapper) {
|
||||
if err := copier.Copy(out, in); err != nil {
|
||||
panic("deep copy failed")
|
||||
}
|
||||
}
|
||||
|
||||
func (in *ConditionsWrapper) DeepCopy() *ConditionsWrapper {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ConditionsWrapper)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (a *ConditionsWrapper) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(a.Conditions)
|
||||
}
|
||||
|
||||
func (a *ConditionsWrapper) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
|
||||
var kyvernoOldConditions []Condition
|
||||
if err = json.Unmarshal(data, &kyvernoOldConditions); err == nil {
|
||||
a.Conditions = kyvernoOldConditions
|
||||
return nil
|
||||
}
|
||||
|
||||
var kyvernoAnyAllConditions AnyAllConditions
|
||||
if err = json.Unmarshal(data, &kyvernoAnyAllConditions); err == nil {
|
||||
a.Conditions = kyvernoAnyAllConditions
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to unmarshal Conditions")
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,72 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by register-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName specifies the group name used to register the objects.
|
||||
const GroupName = "kyverno.io"
|
||||
|
||||
// GroupVersion specifies the group and the version used to register the objects.
|
||||
var GroupVersion = metav1.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
// Deprecated: use GroupVersion instead.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// Deprecated: use Install instead
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
Install = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ClusterPolicy{},
|
||||
&ClusterPolicyList{},
|
||||
&Policy{},
|
||||
&PolicyList{},
|
||||
)
|
||||
// AddToGroupVersion allows the serialization of client types like ListOptions.
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=clusterpolicies,scope="Cluster",shortName=cpol,categories=kyverno
|
||||
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
|
||||
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1
|
||||
// +kubebuilder:printcolumn:name="VALIDATE",type=integer,JSONPath=`.status.rulecount.validate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MUTATE",type=integer,JSONPath=`.status.rulecount.mutate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="GENERATE",type=integer,JSONPath=`.status.rulecount.generate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="VERIFY IMAGES",type=integer,JSONPath=`.status.rulecount.verifyimages`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MESSAGE",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].message`
|
||||
|
||||
// ClusterPolicy declares validation, mutation, and generation behaviors for matching resources.
|
||||
type ClusterPolicy struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec declares policy behaviors.
|
||||
Spec Spec `json:"spec"`
|
||||
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status kyvernov1.PolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterPolicyList is a list of ClusterPolicy instances.
|
||||
type ClusterPolicyList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []ClusterPolicy `json:"items"`
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kjson "github.com/kyverno/kyverno-json/pkg/apis/policy/v1alpha1"
|
||||
"github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno"
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
)
|
||||
|
||||
// AssertionTree defines a kyverno-json assertion tree.
|
||||
type AssertionTree = kjson.Any
|
||||
|
||||
// Validation defines checks to be performed on matching resources.
|
||||
type Validation struct {
|
||||
// FailureAction defines if a validation policy rule violation should block
|
||||
// the admission review request (Enforce), or allow (Audit) the admission review request
|
||||
// and report an error in a policy report. Optional.
|
||||
// Allowed values are Audit or Enforce.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Audit;Enforce
|
||||
FailureAction *kyvernov1.ValidationFailureAction `json:"failureAction,omitempty"`
|
||||
|
||||
// FailureActionOverrides is a Cluster Policy attribute that specifies FailureAction
|
||||
// namespace-wise. It overrides FailureAction for the specified namespaces.
|
||||
// +optional
|
||||
FailureActionOverrides []kyvernov1.ValidationFailureActionOverride `json:"failureActionOverrides,omitempty"`
|
||||
|
||||
// Message specifies a custom message to be displayed on failure.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// Manifest specifies conditions for manifest verification
|
||||
// +optional
|
||||
Manifests *kyvernov1.Manifests `json:"manifests,omitempty"`
|
||||
|
||||
// ForEach applies validate rules to a list of sub-elements by creating a context for each entry in the list and looping over it to apply the specified logic.
|
||||
// +optional
|
||||
ForEachValidation []kyvernov1.ForEachValidation `json:"foreach,omitempty"`
|
||||
|
||||
// Pattern specifies an overlay-style pattern used to check resources.
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawPattern *kyverno.Any `json:"pattern,omitempty"`
|
||||
|
||||
// AnyPattern specifies list of validation patterns. At least one of the patterns
|
||||
// must be satisfied for the validation rule to succeed.
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawAnyPattern *kyverno.Any `json:"anyPattern,omitempty"`
|
||||
|
||||
// Deny defines conditions used to pass or fail a validation rule.
|
||||
// +optional
|
||||
Deny *Deny `json:"deny,omitempty"`
|
||||
|
||||
// PodSecurity applies exemptions for Kubernetes Pod Security admission
|
||||
// by specifying exclusions for Pod Security Standards controls.
|
||||
// +optional
|
||||
PodSecurity *kyvernov1.PodSecurity `json:"podSecurity,omitempty"`
|
||||
|
||||
// CEL allows validation checks using the Common Expression Language (https://kubernetes.io/docs/reference/using-api/cel/).
|
||||
// +optional
|
||||
CEL *kyvernov1.CEL `json:"cel,omitempty"`
|
||||
|
||||
// Assert defines a kyverno-json assertion tree.
|
||||
// +optional
|
||||
Assert AssertionTree `json:"assert"`
|
||||
}
|
||||
|
||||
// ConditionOperator is the operation performed on condition key and value.
|
||||
// +kubebuilder:validation:Enum=Equals;NotEquals;AnyIn;AllIn;AnyNotIn;AllNotIn;GreaterThanOrEquals;GreaterThan;LessThanOrEquals;LessThan;DurationGreaterThanOrEquals;DurationGreaterThan;DurationLessThanOrEquals;DurationLessThan
|
||||
type ConditionOperator string
|
||||
|
||||
// ConditionOperators stores all the valid ConditionOperator types as key-value pairs.
|
||||
// "Equals" evaluates if the key is equal to the value.
|
||||
// "NotEquals" evaluates if the key is not equal to the value.
|
||||
// "AnyIn" evaluates if any of the keys are contained in the set of values.
|
||||
// "AllIn" evaluates if all the keys are contained in the set of values.
|
||||
// "AnyNotIn" evaluates if any of the keys are not contained in the set of values.
|
||||
// "AllNotIn" evaluates if all the keys are not contained in the set of values.
|
||||
// "GreaterThanOrEquals" evaluates if the key (numeric) is greater than or equal to the value (numeric).
|
||||
// "GreaterThan" evaluates if the key (numeric) is greater than the value (numeric).
|
||||
// "LessThanOrEquals" evaluates if the key (numeric) is less than or equal to the value (numeric).
|
||||
// "LessThan" evaluates if the key (numeric) is less than the value (numeric).
|
||||
// "DurationGreaterThanOrEquals" evaluates if the key (duration) is greater than or equal to the value (duration)
|
||||
// "DurationGreaterThan" evaluates if the key (duration) is greater than the value (duration)
|
||||
// "DurationLessThanOrEquals" evaluates if the key (duration) is less than or equal to the value (duration)
|
||||
// "DurationLessThan" evaluates if the key (duration) is greater than the value (duration)
|
||||
var ConditionOperators = map[string]ConditionOperator{
|
||||
"Equals": ConditionOperator("Equals"),
|
||||
"NotEquals": ConditionOperator("NotEquals"),
|
||||
"AnyIn": ConditionOperator("AnyIn"),
|
||||
"AllIn": ConditionOperator("AllIn"),
|
||||
"AnyNotIn": ConditionOperator("AnyNotIn"),
|
||||
"AllNotIn": ConditionOperator("AllNotIn"),
|
||||
"GreaterThanOrEquals": ConditionOperator("GreaterThanOrEquals"),
|
||||
"GreaterThan": ConditionOperator("GreaterThan"),
|
||||
"LessThanOrEquals": ConditionOperator("LessThanOrEquals"),
|
||||
"LessThan": ConditionOperator("LessThan"),
|
||||
"DurationGreaterThanOrEquals": ConditionOperator("DurationGreaterThanOrEquals"),
|
||||
"DurationGreaterThan": ConditionOperator("DurationGreaterThan"),
|
||||
"DurationLessThanOrEquals": ConditionOperator("DurationLessThanOrEquals"),
|
||||
"DurationLessThan": ConditionOperator("DurationLessThan"),
|
||||
}
|
||||
|
||||
// Deny specifies a list of conditions used to pass or fail a validation rule.
|
||||
type Deny struct {
|
||||
// Multiple conditions can be declared under an `any` or `all` statement.
|
||||
// See: https://kyverno.io/docs/writing-policies/validate/#deny-rules
|
||||
RawAnyAllConditions *AnyAllConditions `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
type Condition struct {
|
||||
// Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawKey *kyverno.Any `json:"key,omitempty"`
|
||||
|
||||
// Operator is the conditional operation to perform. Valid operators are:
|
||||
// Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals,
|
||||
// GreaterThan, LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, DurationGreaterThan,
|
||||
// DurationLessThanOrEquals, DurationLessThan
|
||||
Operator ConditionOperator `json:"operator,omitempty"`
|
||||
|
||||
// Value is the conditional value, or set of values. The values can be fixed set
|
||||
// or can be variables declared using JMESPath.
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
RawValue *kyverno.Any `json:"value,omitempty"`
|
||||
|
||||
// Message is an optional display message
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Condition) GetKey() any {
|
||||
return kyverno.FromAny(c.RawKey)
|
||||
}
|
||||
|
||||
func (c *Condition) SetKey(in any) {
|
||||
c.RawKey = kyverno.ToAny(in)
|
||||
}
|
||||
|
||||
func (c *Condition) GetValue() any {
|
||||
return kyverno.FromAny(c.RawValue)
|
||||
}
|
||||
|
||||
func (c *Condition) SetValue(in any) {
|
||||
c.RawValue = kyverno.ToAny(in)
|
||||
}
|
||||
|
||||
type AnyAllConditions struct {
|
||||
// AnyConditions enable variable-based conditional rule execution. This is useful for
|
||||
// finer control of when an rule is applied. A condition can reference object data
|
||||
// using JMESPath notation.
|
||||
// Here, at least one of the conditions need to pass.
|
||||
// +optional
|
||||
AnyConditions []Condition `json:"any,omitempty"`
|
||||
|
||||
// AllConditions enable variable-based conditional rule execution. This is useful for
|
||||
// finer control of when an rule is applied. A condition can reference object data
|
||||
// using JMESPath notation.
|
||||
// Here, all of the conditions need to pass.
|
||||
// +optional
|
||||
AllConditions []Condition `json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// ResourceFilters is a slice of ResourceFilter
|
||||
type ResourceFilters []ResourceFilter
|
||||
|
||||
// ResourceFilter allow users to "AND" or "OR" between resources
|
||||
type ResourceFilter struct {
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
// +optional
|
||||
kyvernov1.UserInfo `json:",omitempty"`
|
||||
|
||||
// ResourceDescription contains information about the resource being created or modified.
|
||||
ResourceDescription `json:"resources,omitempty"`
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=kyverno.io
|
||||
|
||||
package v2beta1
|
|
@ -0,0 +1,77 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
)
|
||||
|
||||
// ImageVerification validates that images that match the specified pattern
|
||||
// are signed with the supplied public key. Once the image is verified it is
|
||||
// mutated to include the SHA digest retrieved during the registration.
|
||||
type ImageVerification struct {
|
||||
// Allowed values are Audit or Enforce.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Audit;Enforce
|
||||
FailureAction *kyvernov1.ValidationFailureAction `json:"failureAction,omitempty"`
|
||||
|
||||
// Type specifies the method of signature validation. The allowed options
|
||||
// are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||
// +kubebuilder:validation:Optional
|
||||
Type kyvernov1.ImageVerificationType `json:"type,omitempty"`
|
||||
|
||||
// ImageReferences is a list of matching image reference patterns. At least one pattern in the
|
||||
// list must match the image for the rule to apply. Each image reference consists of a registry
|
||||
// address (defaults to docker.io), repository, image, and tag (defaults to latest).
|
||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// +kubebuilder:validation:Optional
|
||||
ImageReferences []string `json:"imageReferences,omitempty"`
|
||||
|
||||
// SkipImageReferences is a list of matching image reference patterns that should be skipped.
|
||||
// At least one pattern in the list must match the image for the rule to be skipped. Each image reference
|
||||
// consists of a registry address (defaults to docker.io), repository, image, and tag (defaults to latest).
|
||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// +kubebuilder:validation:Optional
|
||||
SkipImageReferences []string `json:"skipImageReferences,omitempty"`
|
||||
|
||||
// Attestors specified the required attestors (i.e. authorities)
|
||||
// +kubebuilder:validation:Optional
|
||||
Attestors []kyvernov1.AttestorSet `json:"attestors,omitempty"`
|
||||
|
||||
// Attestations are optional checks for signed in-toto Statements used to verify the image.
|
||||
// See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the
|
||||
// OCI registry and decodes them into a list of Statement declarations.
|
||||
Attestations []kyvernov1.Attestation `json:"attestations,omitempty"`
|
||||
|
||||
// Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule.
|
||||
// If specified Repository will override the default OCI image repository configured for the installation.
|
||||
// The repository can also be overridden per Attestor or Attestation.
|
||||
Repository string `json:"repository,omitempty"`
|
||||
|
||||
// MutateDigest enables replacement of image tags with digests.
|
||||
// Defaults to true.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
MutateDigest bool `json:"mutateDigest"`
|
||||
|
||||
// VerifyDigest validates that images have a digest.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
VerifyDigest bool `json:"verifyDigest"`
|
||||
|
||||
// Validation checks conditions across multiple image
|
||||
// verification attestations or context entries
|
||||
Validation kyvernov1.ValidateImageVerification `json:"validate,omitempty"`
|
||||
|
||||
// Required validates that images are verified i.e. have matched passed a signature or attestation check.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
Required bool `json:"required"`
|
||||
|
||||
// ImageRegistryCredentials provides credentials that will be used for authentication with registry
|
||||
// +kubebuilder:validation:Optional
|
||||
ImageRegistryCredentials *kyvernov1.ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty"`
|
||||
|
||||
// UseCache enables caching of image verify responses for this rule
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
UseCache bool `json:"useCache"`
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
)
|
||||
|
||||
// MatchResources is used to specify resource and admission review request data for
|
||||
// which a policy rule is applicable.
|
||||
// +kubebuilder:not:={required:{any,all}}
|
||||
type MatchResources struct {
|
||||
// Any allows specifying resources which will be ORed
|
||||
// +optional
|
||||
Any kyvernov1.ResourceFilters `json:"any,omitempty"`
|
||||
|
||||
// All allows specifying resources which will be ANDed
|
||||
// +optional
|
||||
All kyvernov1.ResourceFilters `json:"all,omitempty"`
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright 2022 The Kubernetes authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:shortName=polex,categories=kyverno
|
||||
// +kubebuilder:deprecatedversion
|
||||
|
||||
// PolicyException declares resources to be excluded from specified policies.
|
||||
type PolicyException struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec declares policy exception behaviors.
|
||||
Spec PolicyExceptionSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// PolicyExceptionSpec stores policy exception spec
|
||||
type PolicyExceptionSpec struct {
|
||||
// Background controls if exceptions are applied to existing policies during a background scan.
|
||||
// Optional. Default value is "true". The value must be set to "false" if the policy rule
|
||||
// uses variables that are only available in the admission review request (e.g. user name).
|
||||
Background *bool `json:"background,omitempty"`
|
||||
|
||||
// Match defines match clause used to check if a resource applies to the exception
|
||||
Match MatchResources `json:"match"`
|
||||
|
||||
// Conditions are used to determine if a resource applies to the exception by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements.
|
||||
// +optional
|
||||
Conditions *AnyAllConditions `json:"conditions,omitempty"`
|
||||
|
||||
// Exceptions is a list policy/rules to be excluded
|
||||
Exceptions []Exception `json:"exceptions"`
|
||||
|
||||
// PodSecurity specifies the Pod Security Standard controls to be excluded.
|
||||
// Applicable only to policies that have validate.podSecurity subrule.
|
||||
// +optional
|
||||
PodSecurity []kyvernov1.PodSecurityStandard `json:"podSecurity,omitempty"`
|
||||
}
|
||||
|
||||
// Exception stores infos about a policy and rules
|
||||
type Exception struct {
|
||||
// PolicyName identifies the policy to which the exception is applied.
|
||||
// The policy name uses the format <namespace>/<name> unless it
|
||||
// references a ClusterPolicy.
|
||||
PolicyName string `json:"policyName"`
|
||||
|
||||
// RuleNames identifies the rules to which the exception is applied.
|
||||
RuleNames []string `json:"ruleNames"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PolicyExceptionList is a list of Policy Exceptions
|
||||
type PolicyExceptionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []PolicyException `json:"items"`
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
|
||||
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1
|
||||
// +kubebuilder:printcolumn:name="VALIDATE",type=integer,JSONPath=`.status.rulecount.validate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MUTATE",type=integer,JSONPath=`.status.rulecount.mutate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="GENERATE",type=integer,JSONPath=`.status.rulecount.generate`,priority=1
|
||||
// +kubebuilder:printcolumn:name="VERIFY IMAGES",type=integer,JSONPath=`.status.rulecount.verifyimages`,priority=1
|
||||
// +kubebuilder:printcolumn:name="MESSAGE",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].message`
|
||||
// +kubebuilder:resource:shortName=pol,categories=kyverno
|
||||
|
||||
// Policy declares validation, mutation, and generation behaviors for matching resources.
|
||||
// See: https://kyverno.io/docs/writing-policies/ for more information.
|
||||
type Policy struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines policy behaviors and contains one or more rules.
|
||||
Spec Spec `json:"spec"`
|
||||
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status kyvernov1.PolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (p *Policy) GetKind() string {
|
||||
return p.Kind
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PolicyList is a list of Policy instances.
|
||||
type PolicyList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []Policy `json:"items"`
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ResourceDescription contains criteria used to match resources.
|
||||
type ResourceDescription struct {
|
||||
// Kinds is a list of resource kinds.
|
||||
// +optional
|
||||
Kinds []string `json:"kinds,omitempty"`
|
||||
|
||||
// Names are the names of the resources. Each name supports wildcard characters
|
||||
// "*" (matches zero or many characters) and "?" (at least one character).
|
||||
// +optional
|
||||
Names []string `json:"names,omitempty"`
|
||||
|
||||
// Namespaces is a list of namespaces names. Each name supports wildcard characters
|
||||
// "*" (matches zero or many characters) and "?" (at least one character).
|
||||
// +optional
|
||||
Namespaces []string `json:"namespaces,omitempty"`
|
||||
|
||||
// Annotations is a map of annotations (key-value pairs of type string). Annotation keys
|
||||
// and values support the wildcard characters "*" (matches zero or many characters) and
|
||||
// "?" (matches at least one character).
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Selector is a label selector. Label keys and values in `matchLabels` support the wildcard
|
||||
// characters `*` (matches zero or many characters) and `?` (matches one character).
|
||||
// Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that
|
||||
// using ["*" : "*"] matches any key and value but does not match an empty label set.
|
||||
// +optional
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// NamespaceSelector is a label selector for the resource namespace. Label keys and values
|
||||
// in `matchLabels` support the wildcard characters `*` (matches zero or many characters)
|
||||
// and `?` (matches one character).Wildcards allows writing label selectors like
|
||||
// ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but
|
||||
// does not match an empty label set.
|
||||
// +optional
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
|
||||
|
||||
// Operations can contain values ["CREATE, "UPDATE", "CONNECT", "DELETE"], which are used to match a specific action.
|
||||
// +optional
|
||||
Operations []kyvernov1.AdmissionOperation `json:"operations,omitempty"`
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
)
|
||||
|
||||
// Rule defines a validation, mutation, or generation control for matching resources.
|
||||
// Each rules contains a match declaration to select resources, and an optional exclude
|
||||
// declaration to specify which resources to exclude.
|
||||
type Rule struct {
|
||||
// Name is a label to identify the rule, It must be unique within the policy.
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
Name string `json:"name"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []kyvernov1.ContextEntry `json:"context,omitempty"`
|
||||
|
||||
// MatchResources defines when this policy rule should be applied. The match
|
||||
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
||||
// and admission review request information like the user name or role.
|
||||
// At least one kind is required.
|
||||
MatchResources MatchResources `json:"match"`
|
||||
|
||||
// ExcludeResources defines when this policy rule should not be applied. The exclude
|
||||
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
||||
// and admission review request information like the name or role.
|
||||
// +optional
|
||||
ExcludeResources *MatchResources `json:"exclude,omitempty"`
|
||||
|
||||
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
||||
// This config is only valid for verifyImages rules.
|
||||
// +optional
|
||||
ImageExtractors kyvernov1.ImageExtractorConfigs `json:"imageExtractors,omitempty"`
|
||||
|
||||
// Preconditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements.
|
||||
// See: https://kyverno.io/docs/writing-policies/preconditions/
|
||||
// +optional
|
||||
RawAnyAllConditions *AnyAllConditions `json:"preconditions,omitempty"`
|
||||
|
||||
// CELPreconditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of CEL conditions. It can only be used with the validate.cel subrule
|
||||
// +optional
|
||||
CELPreconditions []admissionregistrationv1.MatchCondition `json:"celPreconditions,omitempty"`
|
||||
|
||||
// Mutation is used to modify matching resources.
|
||||
// +optional
|
||||
Mutation *kyvernov1.Mutation `json:"mutate,omitempty"`
|
||||
|
||||
// Validation is used to validate matching resources.
|
||||
// +optional
|
||||
Validation *Validation `json:"validate,omitempty"`
|
||||
|
||||
// Generation is used to create new resources.
|
||||
// +optional
|
||||
Generation *kyvernov1.Generation `json:"generate,omitempty"`
|
||||
|
||||
// VerifyImages is used to verify image signatures and mutate them to add a digest
|
||||
// +optional
|
||||
VerifyImages []ImageVerification `json:"verifyImages,omitempty"`
|
||||
|
||||
// SkipBackgroundRequests bypasses admission requests that are sent by the background controller.
|
||||
// The default value is set to "true", it must be set to "false" to apply
|
||||
// generate and mutateExisting rules to those requests.
|
||||
// +kubebuilder:default=true
|
||||
// +kubebuilder:validation:Optional
|
||||
SkipBackgroundRequests *bool `json:"skipBackgroundRequests,omitempty"`
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
)
|
||||
|
||||
// Spec contains a list of Rule instances and other policy controls.
|
||||
type Spec struct {
|
||||
// Rules is a list of Rule instances. A Policy contains multiple rules and
|
||||
// each rule can validate, mutate, or generate resources.
|
||||
Rules []Rule `json:"rules,omitempty"`
|
||||
|
||||
// ApplyRules controls how rules in a policy are applied. Rule are processed in
|
||||
// the order of declaration. When set to `One` processing stops after a rule has
|
||||
// been applied i.e. the rule matches and results in a pass, fail, or error. When
|
||||
// set to `All` all rules in the policy are processed. The default is `All`.
|
||||
// +optional
|
||||
ApplyRules *kyvernov1.ApplyRulesType `json:"applyRules,omitempty"`
|
||||
|
||||
// Deprecated, use failurePolicy under the webhookConfiguration instead.
|
||||
FailurePolicy *kyvernov1.FailurePolicyType `json:"failurePolicy,omitempty"`
|
||||
|
||||
// Deprecated, use validationFailureAction under the validate rule instead.
|
||||
// +kubebuilder:validation:Enum=audit;enforce;Audit;Enforce
|
||||
// +kubebuilder:default=Audit
|
||||
ValidationFailureAction kyvernov1.ValidationFailureAction `json:"validationFailureAction,omitempty"`
|
||||
|
||||
// Deprecated, use validationFailureActionOverrides under the validate rule instead.
|
||||
ValidationFailureActionOverrides []kyvernov1.ValidationFailureActionOverride `json:"validationFailureActionOverrides,omitempty"`
|
||||
|
||||
// EmitWarning enables API response warnings for mutate policy rules or validate policy rules with validationFailureAction set to Audit.
|
||||
// Enabling this option will extend admission request processing times. The default value is "false".
|
||||
// +optional
|
||||
// +kubebuilder:default=false
|
||||
EmitWarning *bool `json:"emitWarning,omitempty"`
|
||||
|
||||
// Admission controls if rules are applied during admission.
|
||||
// Optional. Default value is "true".
|
||||
// +optional
|
||||
// +kubebuilder:default=true
|
||||
Admission *bool `json:"admission,omitempty"`
|
||||
|
||||
// Background controls if rules are applied to existing resources during a background scan.
|
||||
// Optional. Default value is "true". The value must be set to "false" if the policy rule
|
||||
// uses variables that are only available in the admission review request (e.g. user name).
|
||||
// +optional
|
||||
// +kubebuilder:default=true
|
||||
Background *bool `json:"background,omitempty"`
|
||||
|
||||
// Deprecated.
|
||||
SchemaValidation *bool `json:"schemaValidation,omitempty"`
|
||||
|
||||
// Deprecated, use webhookTimeoutSeconds under webhookConfiguration instead.
|
||||
WebhookTimeoutSeconds *int32 `json:"webhookTimeoutSeconds,omitempty"`
|
||||
|
||||
// Deprecated, use mutateExistingOnPolicyUpdate under the mutate rule instead
|
||||
// +optional
|
||||
MutateExistingOnPolicyUpdate bool `json:"mutateExistingOnPolicyUpdate,omitempty"`
|
||||
|
||||
// Deprecated, use generateExisting instead
|
||||
// +optional
|
||||
GenerateExistingOnPolicyUpdate *bool `json:"generateExistingOnPolicyUpdate,omitempty"`
|
||||
|
||||
// Deprecated, use generateExisting under the generate rule instead
|
||||
GenerateExisting bool `json:"generateExisting,omitempty"`
|
||||
|
||||
// UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
// If is set to "true" create & update for generate rules will use apply instead of create/update.
|
||||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
UseServerSideApply bool `json:"useServerSideApply,omitempty"`
|
||||
|
||||
// WebhookConfiguration specifies the custom configuration for Kubernetes admission webhookconfiguration.
|
||||
// +optional
|
||||
WebhookConfiguration *kyvernov1.WebhookConfiguration `json:"webhookConfiguration,omitempty"`
|
||||
}
|
|
@ -0,0 +1,742 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
v1 "github.com/kyverno/policy-reporter/kyverno-plugin/pkg/crd/api/kyverno/v1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AnyAllConditions) DeepCopyInto(out *AnyAllConditions) {
|
||||
*out = *in
|
||||
if in.AnyConditions != nil {
|
||||
in, out := &in.AnyConditions, &out.AnyConditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.AllConditions != nil {
|
||||
in, out := &in.AllConditions, &out.AllConditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnyAllConditions.
|
||||
func (in *AnyAllConditions) DeepCopy() *AnyAllConditions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AnyAllConditions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterPolicy) DeepCopyInto(out *ClusterPolicy) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicy.
|
||||
func (in *ClusterPolicy) DeepCopy() *ClusterPolicy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterPolicy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterPolicy) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterPolicyList) DeepCopyInto(out *ClusterPolicyList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ClusterPolicy, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyList.
|
||||
func (in *ClusterPolicyList) DeepCopy() *ClusterPolicyList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterPolicyList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterPolicyList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Condition) DeepCopyInto(out *Condition) {
|
||||
*out = *in
|
||||
if in.RawKey != nil {
|
||||
in, out := &in.RawKey, &out.RawKey
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.RawValue != nil {
|
||||
in, out := &in.RawValue, &out.RawValue
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
|
||||
func (in *Condition) DeepCopy() *Condition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Condition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Deny) DeepCopyInto(out *Deny) {
|
||||
*out = *in
|
||||
if in.RawAnyAllConditions != nil {
|
||||
in, out := &in.RawAnyAllConditions, &out.RawAnyAllConditions
|
||||
*out = new(AnyAllConditions)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Deny.
|
||||
func (in *Deny) DeepCopy() *Deny {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Deny)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Exception) DeepCopyInto(out *Exception) {
|
||||
*out = *in
|
||||
if in.RuleNames != nil {
|
||||
in, out := &in.RuleNames, &out.RuleNames
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Exception.
|
||||
func (in *Exception) DeepCopy() *Exception {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Exception)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageVerification) DeepCopyInto(out *ImageVerification) {
|
||||
*out = *in
|
||||
if in.FailureAction != nil {
|
||||
in, out := &in.FailureAction, &out.FailureAction
|
||||
*out = new(v1.ValidationFailureAction)
|
||||
**out = **in
|
||||
}
|
||||
if in.ImageReferences != nil {
|
||||
in, out := &in.ImageReferences, &out.ImageReferences
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SkipImageReferences != nil {
|
||||
in, out := &in.SkipImageReferences, &out.SkipImageReferences
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Attestors != nil {
|
||||
in, out := &in.Attestors, &out.Attestors
|
||||
*out = make([]v1.AttestorSet, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Attestations != nil {
|
||||
in, out := &in.Attestations, &out.Attestations
|
||||
*out = make([]v1.Attestation, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.Validation.DeepCopyInto(&out.Validation)
|
||||
if in.ImageRegistryCredentials != nil {
|
||||
in, out := &in.ImageRegistryCredentials, &out.ImageRegistryCredentials
|
||||
*out = new(v1.ImageRegistryCredentials)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageVerification.
|
||||
func (in *ImageVerification) DeepCopy() *ImageVerification {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ImageVerification)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MatchResources) DeepCopyInto(out *MatchResources) {
|
||||
*out = *in
|
||||
if in.Any != nil {
|
||||
in, out := &in.Any, &out.Any
|
||||
*out = make(v1.ResourceFilters, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.All != nil {
|
||||
in, out := &in.All, &out.All
|
||||
*out = make(v1.ResourceFilters, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchResources.
|
||||
func (in *MatchResources) DeepCopy() *MatchResources {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MatchResources)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Policy) DeepCopyInto(out *Policy) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Policy.
|
||||
func (in *Policy) DeepCopy() *Policy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Policy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Policy) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyException) DeepCopyInto(out *PolicyException) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyException.
|
||||
func (in *PolicyException) DeepCopy() *PolicyException {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyException)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyException) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyExceptionList) DeepCopyInto(out *PolicyExceptionList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]PolicyException, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyExceptionList.
|
||||
func (in *PolicyExceptionList) DeepCopy() *PolicyExceptionList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyExceptionList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyExceptionList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyExceptionSpec) DeepCopyInto(out *PolicyExceptionSpec) {
|
||||
*out = *in
|
||||
if in.Background != nil {
|
||||
in, out := &in.Background, &out.Background
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
in.Match.DeepCopyInto(&out.Match)
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = new(AnyAllConditions)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Exceptions != nil {
|
||||
in, out := &in.Exceptions, &out.Exceptions
|
||||
*out = make([]Exception, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.PodSecurity != nil {
|
||||
in, out := &in.PodSecurity, &out.PodSecurity
|
||||
*out = make([]v1.PodSecurityStandard, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyExceptionSpec.
|
||||
func (in *PolicyExceptionSpec) DeepCopy() *PolicyExceptionSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyExceptionSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyList) DeepCopyInto(out *PolicyList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Policy, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyList.
|
||||
func (in *PolicyList) DeepCopy() *PolicyList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) {
|
||||
*out = *in
|
||||
if in.Kinds != nil {
|
||||
in, out := &in.Kinds, &out.Kinds
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Names != nil {
|
||||
in, out := &in.Names, &out.Names
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Namespaces != nil {
|
||||
in, out := &in.Namespaces, &out.Namespaces
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(metav1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.NamespaceSelector != nil {
|
||||
in, out := &in.NamespaceSelector, &out.NamespaceSelector
|
||||
*out = new(metav1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Operations != nil {
|
||||
in, out := &in.Operations, &out.Operations
|
||||
*out = make([]v1.AdmissionOperation, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceDescription.
|
||||
func (in *ResourceDescription) DeepCopy() *ResourceDescription {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceDescription)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) {
|
||||
*out = *in
|
||||
in.UserInfo.DeepCopyInto(&out.UserInfo)
|
||||
in.ResourceDescription.DeepCopyInto(&out.ResourceDescription)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilter.
|
||||
func (in *ResourceFilter) DeepCopy() *ResourceFilter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceFilter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ResourceFilters) DeepCopyInto(out *ResourceFilters) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ResourceFilters, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilters.
|
||||
func (in ResourceFilters) DeepCopy() ResourceFilters {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceFilters)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Rule) DeepCopyInto(out *Rule) {
|
||||
*out = *in
|
||||
if in.Context != nil {
|
||||
in, out := &in.Context, &out.Context
|
||||
*out = make([]v1.ContextEntry, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.MatchResources.DeepCopyInto(&out.MatchResources)
|
||||
if in.ExcludeResources != nil {
|
||||
in, out := &in.ExcludeResources, &out.ExcludeResources
|
||||
*out = new(MatchResources)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ImageExtractors != nil {
|
||||
in, out := &in.ImageExtractors, &out.ImageExtractors
|
||||
*out = make(v1.ImageExtractorConfigs, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []v1.ImageExtractorConfig
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]v1.ImageExtractorConfig, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.RawAnyAllConditions != nil {
|
||||
in, out := &in.RawAnyAllConditions, &out.RawAnyAllConditions
|
||||
*out = new(AnyAllConditions)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.CELPreconditions != nil {
|
||||
in, out := &in.CELPreconditions, &out.CELPreconditions
|
||||
*out = make([]admissionregistrationv1.MatchCondition, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Mutation != nil {
|
||||
in, out := &in.Mutation, &out.Mutation
|
||||
*out = new(v1.Mutation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Validation != nil {
|
||||
in, out := &in.Validation, &out.Validation
|
||||
*out = new(Validation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Generation != nil {
|
||||
in, out := &in.Generation, &out.Generation
|
||||
*out = new(v1.Generation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.VerifyImages != nil {
|
||||
in, out := &in.VerifyImages, &out.VerifyImages
|
||||
*out = make([]ImageVerification, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SkipBackgroundRequests != nil {
|
||||
in, out := &in.SkipBackgroundRequests, &out.SkipBackgroundRequests
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
|
||||
func (in *Rule) DeepCopy() *Rule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Rule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Spec) DeepCopyInto(out *Spec) {
|
||||
*out = *in
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]Rule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.ApplyRules != nil {
|
||||
in, out := &in.ApplyRules, &out.ApplyRules
|
||||
*out = new(v1.ApplyRulesType)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailurePolicy != nil {
|
||||
in, out := &in.FailurePolicy, &out.FailurePolicy
|
||||
*out = new(v1.FailurePolicyType)
|
||||
**out = **in
|
||||
}
|
||||
if in.ValidationFailureActionOverrides != nil {
|
||||
in, out := &in.ValidationFailureActionOverrides, &out.ValidationFailureActionOverrides
|
||||
*out = make([]v1.ValidationFailureActionOverride, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.EmitWarning != nil {
|
||||
in, out := &in.EmitWarning, &out.EmitWarning
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Admission != nil {
|
||||
in, out := &in.Admission, &out.Admission
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Background != nil {
|
||||
in, out := &in.Background, &out.Background
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.SchemaValidation != nil {
|
||||
in, out := &in.SchemaValidation, &out.SchemaValidation
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.WebhookTimeoutSeconds != nil {
|
||||
in, out := &in.WebhookTimeoutSeconds, &out.WebhookTimeoutSeconds
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.GenerateExistingOnPolicyUpdate != nil {
|
||||
in, out := &in.GenerateExistingOnPolicyUpdate, &out.GenerateExistingOnPolicyUpdate
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.WebhookConfiguration != nil {
|
||||
in, out := &in.WebhookConfiguration, &out.WebhookConfiguration
|
||||
*out = new(v1.WebhookConfiguration)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Spec.
|
||||
func (in *Spec) DeepCopy() *Spec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Spec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Validation) DeepCopyInto(out *Validation) {
|
||||
*out = *in
|
||||
if in.FailureAction != nil {
|
||||
in, out := &in.FailureAction, &out.FailureAction
|
||||
*out = new(v1.ValidationFailureAction)
|
||||
**out = **in
|
||||
}
|
||||
if in.FailureActionOverrides != nil {
|
||||
in, out := &in.FailureActionOverrides, &out.FailureActionOverrides
|
||||
*out = make([]v1.ValidationFailureActionOverride, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Manifests != nil {
|
||||
in, out := &in.Manifests, &out.Manifests
|
||||
*out = new(v1.Manifests)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ForEachValidation != nil {
|
||||
in, out := &in.ForEachValidation, &out.ForEachValidation
|
||||
*out = make([]v1.ForEachValidation, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.RawPattern != nil {
|
||||
in, out := &in.RawPattern, &out.RawPattern
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.RawAnyPattern != nil {
|
||||
in, out := &in.RawAnyPattern, &out.RawAnyPattern
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.Deny != nil {
|
||||
in, out := &in.Deny, &out.Deny
|
||||
*out = new(Deny)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PodSecurity != nil {
|
||||
in, out := &in.PodSecurity, &out.PodSecurity
|
||||
*out = new(v1.PodSecurity)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.CEL != nil {
|
||||
in, out := &in.CEL, &out.CEL
|
||||
*out = new(v1.CEL)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Assert.DeepCopyInto(&out.Assert)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Validation.
|
||||
func (in *Validation) DeepCopy() *Validation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Validation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by register-gen. DO NOT EDIT.
|
||||
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName specifies the group name used to register the objects.
|
||||
const GroupName = "kyverno.io"
|
||||
|
||||
// GroupVersion specifies the group and the version used to register the objects.
|
||||
var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v2beta1"}
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
// Deprecated: use GroupVersion instead.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v2beta1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// Deprecated: use Install instead
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
Install = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ClusterPolicy{},
|
||||
&ClusterPolicyList{},
|
||||
&Policy{},
|
||||
&PolicyException{},
|
||||
&PolicyExceptionList{},
|
||||
&PolicyList{},
|
||||
)
|
||||
// AddToGroupVersion allows the serialization of client types like ListOptions.
|
||||
v1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package v1alpha1
|
||||
|
||||
type PodControllersGenerationConfiguration struct {
|
||||
Controllers []string `json:"controllers,omitempty"`
|
||||
}
|
||||
|
||||
type Target struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Resource string `json:"resource"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
type ValidatingPolicyAutogenStatus struct {
|
||||
Configs map[string]ValidatingPolicyAutogen `json:"configs,omitempty"`
|
||||
}
|
||||
|
||||
type ImageValidatingPolicyAutogenStatus struct {
|
||||
Configs map[string]ImageValidatingPolicyAutogen `json:"configs,omitempty"`
|
||||
}
|
||||
|
||||
type MutatingPolicyAutogenStatus struct {
|
||||
Configs map[string]MutatingPolicyAutogen `json:"configs,omitempty"`
|
||||
}
|
||||
|
||||
type ValidatingPolicyAutogen struct {
|
||||
Targets []Target `json:"targets"`
|
||||
Spec *ValidatingPolicySpec `json:"spec"`
|
||||
}
|
||||
|
||||
type ImageValidatingPolicyAutogen struct {
|
||||
Targets []Target `json:"targets"`
|
||||
Spec *ImageValidatingPolicySpec `json:"spec"`
|
||||
}
|
||||
|
||||
type MutatingPolicyAutogen struct {
|
||||
Targets []Target `json:"targets"`
|
||||
Spec *MutatingPolicySpec `json:"spec"`
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package v1alpha1
|
||||
|
||||
type EvaluationMode string
|
||||
|
||||
const (
|
||||
EvaluationModeKubernetes EvaluationMode = "Kubernetes"
|
||||
EvaluationModeJSON EvaluationMode = "JSON"
|
||||
)
|
||||
|
||||
type EvaluationConfiguration struct {
|
||||
// Mode is the mode of policy evaluation.
|
||||
// Allowed values are "Kubernetes" or "JSON".
|
||||
// Optional. Default value is "Kubernetes".
|
||||
// +optional
|
||||
Mode EvaluationMode `json:"mode,omitempty"`
|
||||
|
||||
// Admission controls policy evaluation during admission.
|
||||
// +optional
|
||||
Admission *AdmissionConfiguration `json:"admission,omitempty"`
|
||||
|
||||
// Background controls policy evaluation during background scan.
|
||||
// +optional
|
||||
Background *BackgroundConfiguration `json:"background,omitempty"`
|
||||
}
|
||||
|
||||
type AdmissionConfiguration struct {
|
||||
// Enabled controls if rules are applied during admission.
|
||||
// Optional. Default value is "true".
|
||||
// +optional
|
||||
// +kubebuilder:default=true
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
type BackgroundConfiguration struct {
|
||||
// Enabled controls if rules are applied to existing resources during a background scan.
|
||||
// Optional. Default value is "true". The value must be set to "false" if the policy rule
|
||||
// uses variables that are only available in the admission review request (e.g. user name).
|
||||
// +optional
|
||||
// +kubebuilder:default=true
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func TestValidatingPolicySpec_AdmissionEnabled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
policy *ValidatingPolicy
|
||||
want bool
|
||||
}{{
|
||||
name: "nil",
|
||||
policy: &ValidatingPolicy{},
|
||||
want: true,
|
||||
}, {
|
||||
name: "true",
|
||||
policy: &ValidatingPolicy{
|
||||
Spec: ValidatingPolicySpec{
|
||||
EvaluationConfiguration: &EvaluationConfiguration{
|
||||
Admission: &AdmissionConfiguration{
|
||||
Enabled: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: true,
|
||||
}, {
|
||||
name: "false",
|
||||
policy: &ValidatingPolicy{
|
||||
Spec: ValidatingPolicySpec{
|
||||
EvaluationConfiguration: &EvaluationConfiguration{
|
||||
Admission: &AdmissionConfiguration{
|
||||
Enabled: ptr.To(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: false,
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.policy.Spec.AdmissionEnabled()
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatingPolicySpec_BackgroundEnabled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
policy *ValidatingPolicy
|
||||
want bool
|
||||
}{{
|
||||
name: "nil",
|
||||
policy: &ValidatingPolicy{},
|
||||
want: true,
|
||||
}, {
|
||||
name: "true",
|
||||
policy: &ValidatingPolicy{
|
||||
Spec: ValidatingPolicySpec{
|
||||
EvaluationConfiguration: &EvaluationConfiguration{
|
||||
Background: &BackgroundConfiguration{
|
||||
Enabled: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: true,
|
||||
}, {
|
||||
name: "false",
|
||||
policy: &ValidatingPolicy{
|
||||
Spec: ValidatingPolicySpec{
|
||||
EvaluationConfiguration: &EvaluationConfiguration{
|
||||
Background: &BackgroundConfiguration{
|
||||
Enabled: ptr.To(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: false,
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.policy.Spec.BackgroundEnabled()
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatingPolicySpec_EvaluationMode(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
policy *ValidatingPolicy
|
||||
want EvaluationMode
|
||||
}{{
|
||||
name: "nil",
|
||||
policy: &ValidatingPolicy{},
|
||||
want: EvaluationModeKubernetes,
|
||||
}, {
|
||||
name: "json",
|
||||
policy: &ValidatingPolicy{
|
||||
Spec: ValidatingPolicySpec{
|
||||
EvaluationConfiguration: &EvaluationConfiguration{
|
||||
Mode: EvaluationModeJSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: EvaluationModeJSON,
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.policy.Spec.EvaluationMode()
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type PolicyConditionType string
|
||||
|
||||
const (
|
||||
PolicyConditionTypeWebhookConfigured PolicyConditionType = "WebhookConfigured"
|
||||
PolicyConditionTypePolicyCached PolicyConditionType = "PolicyCached"
|
||||
PolicyConditionTypeRBACPermissionsGranted PolicyConditionType = "RBACPermissionsGranted"
|
||||
)
|
||||
|
||||
// ConditionStatus is the shared status across all policy types
|
||||
type ConditionStatus struct {
|
||||
// The ready of a policy is a high-level summary of where the policy is in its lifecycle.
|
||||
// The conditions array, the reason and message fields contain more detail about the policy's status.
|
||||
// +optional
|
||||
Ready *bool `json:"ready,omitempty"`
|
||||
|
||||
// +optional
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
|
||||
// Message is a human readable message indicating details about the generation of ValidatingAdmissionPolicy/MutatingAdmissionPolicy
|
||||
// It is an empty string when ValidatingAdmissionPolicy/MutatingAdmissionPolicy is successfully generated.
|
||||
// +optional
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (status *ConditionStatus) SetReadyByCondition(c PolicyConditionType, s metav1.ConditionStatus, message string) {
|
||||
reason := "Succeeded"
|
||||
if s != metav1.ConditionTrue {
|
||||
reason = "Failed"
|
||||
}
|
||||
newCondition := metav1.Condition{
|
||||
Type: string(c),
|
||||
Reason: reason,
|
||||
Status: s,
|
||||
Message: message,
|
||||
}
|
||||
meta.SetStatusCondition(&status.Conditions, newCondition)
|
||||
}
|
||||
|
||||
func (status ConditionStatus) IsReady() bool {
|
||||
if status.Ready != nil {
|
||||
return *status.Ready
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func TestConditionStatus_IsReady(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
status ValidatingPolicyStatus
|
||||
want bool
|
||||
}{{
|
||||
name: "nil",
|
||||
status: ValidatingPolicyStatus{},
|
||||
want: false,
|
||||
}, {
|
||||
name: "true",
|
||||
status: ValidatingPolicyStatus{
|
||||
ConditionStatus: ConditionStatus{
|
||||
Ready: ptr.To(true),
|
||||
},
|
||||
},
|
||||
want: true,
|
||||
}, {
|
||||
name: "false",
|
||||
status: ValidatingPolicyStatus{
|
||||
ConditionStatus: ConditionStatus{
|
||||
Ready: ptr.To(false),
|
||||
},
|
||||
},
|
||||
want: false,
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.status.GetConditionStatus().IsReady()
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConditionStatus_SetReadyByCondition_True(t *testing.T) {
|
||||
var status ConditionStatus
|
||||
status.SetReadyByCondition(PolicyConditionTypeWebhookConfigured, metav1.ConditionTrue, "dummy")
|
||||
got := meta.FindStatusCondition(status.Conditions, string(PolicyConditionTypeWebhookConfigured))
|
||||
assert.NotNil(t, got)
|
||||
assert.Equal(t, string(PolicyConditionTypeWebhookConfigured), got.Type)
|
||||
assert.Equal(t, metav1.ConditionTrue, got.Status)
|
||||
assert.Equal(t, "Succeeded", got.Reason)
|
||||
assert.Equal(t, "dummy", got.Message)
|
||||
}
|
||||
|
||||
func TestConditionStatus_SetReadyByCondition_False(t *testing.T) {
|
||||
var status ConditionStatus
|
||||
status.SetReadyByCondition(PolicyConditionTypeWebhookConfigured, metav1.ConditionFalse, "dummy")
|
||||
got := meta.FindStatusCondition(status.Conditions, string(PolicyConditionTypeWebhookConfigured))
|
||||
assert.NotNil(t, got)
|
||||
assert.Equal(t, string(PolicyConditionTypeWebhookConfigured), got.Type)
|
||||
assert.Equal(t, metav1.ConditionFalse, got.Status)
|
||||
assert.Equal(t, "Failed", got.Reason)
|
||||
assert.Equal(t, "dummy", got.Message)
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=deletingpolicies,scope="Cluster",shortName=dpol,categories=kyverno
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditionStatus.ready`
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type DeletingPolicy struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec DeletingPolicySpec `json:"spec"`
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status DeletingPolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// DeletingPolicyList is a list of DeletingPolicy instances
|
||||
type DeletingPolicyList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []DeletingPolicy `json:"items"`
|
||||
}
|
||||
|
||||
// DeletingPolicySpec is the specification of the desired behavior of the DeletingPolicy.
|
||||
type DeletingPolicySpec struct {
|
||||
// MatchConstraints specifies what resources this policy is designed to validate.
|
||||
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
|
||||
// Required.
|
||||
MatchConstraints *admissionregistrationv1.MatchResources `json:"matchConstraints,omitempty"`
|
||||
|
||||
// Conditions is a list of conditions that must be met for a resource to be deleted.
|
||||
// Conditions filter resources that have already been matched by the match constraints,
|
||||
// namespaceSelector, and objectSelector. An empty list of conditions matches all resources.
|
||||
// There are a maximum of 64 conditions allowed.
|
||||
//
|
||||
// If a parameter object is provided, it can be accessed via the `params` handle in the same
|
||||
// manner as validation expressions.
|
||||
//
|
||||
// The exact matching logic is (in order):
|
||||
// 1. If ANY condition evaluates to FALSE, the policy is skipped.
|
||||
// 2. If ALL conditions evaluate to TRUE, the policy is executed.
|
||||
//
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
Conditions []admissionregistrationv1.MatchCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
|
||||
// Variables contain definitions of variables that can be used in composition of other expressions.
|
||||
// Each variable is defined as a named CEL expression.
|
||||
// The variables defined here will be available under `variables` in other expressions of the policy
|
||||
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
|
||||
//
|
||||
// The expression of a variable can refer to other variables defined earlier in the list but not those after.
|
||||
// Thus, Variables must be sorted by the order of first appearance and acyclic.
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
Variables []admissionregistrationv1.Variable `json:"variables,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
|
||||
// The schedule in Cron format
|
||||
// Required.
|
||||
Schedule string `json:"schedule"`
|
||||
|
||||
// DeletionPropagationPolicy defines how resources will be deleted (Foreground, Background, Orphan).
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Foreground;Background;Orphan
|
||||
DeletionPropagationPolicy *metav1.DeletionPropagation `json:"deletionPropagationPolicy,omitempty"`
|
||||
}
|
||||
|
||||
type DeletingPolicyStatus struct {
|
||||
// +optional
|
||||
ConditionStatus ConditionStatus `json:"conditionStatus,omitempty"`
|
||||
LastExecutionTime metav1.Time `json:"lastExecutionTime,omitempty"`
|
||||
}
|
||||
|
||||
func (p *DeletingPolicy) GetKind() string {
|
||||
return "DeletingPolicy"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=policies.kyverno.io
|
||||
package v1alpha1
|
|
@ -0,0 +1,229 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=generatingpolicies,scope="Cluster",shortName=gpol,categories=kyverno
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type GeneratingPolicy struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec GeneratingPolicySpec `json:"spec"`
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status GeneratingPolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetMatchConstraints() admissionregistrationv1.MatchResources {
|
||||
if s.Spec.MatchConstraints == nil {
|
||||
return admissionregistrationv1.MatchResources{}
|
||||
}
|
||||
return *s.Spec.MatchConstraints
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetMatchConditions() []admissionregistrationv1.MatchCondition {
|
||||
return s.Spec.MatchConditions
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetFailurePolicy() admissionregistrationv1.FailurePolicyType {
|
||||
return admissionregistrationv1.Ignore
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetWebhookConfiguration() *WebhookConfiguration {
|
||||
return s.Spec.WebhookConfiguration
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetVariables() []admissionregistrationv1.Variable {
|
||||
return s.Spec.Variables
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetSpec() *GeneratingPolicySpec {
|
||||
return &s.Spec
|
||||
}
|
||||
|
||||
func (s *GeneratingPolicy) GetStatus() *GeneratingPolicyStatus {
|
||||
return &s.Status
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// GeneratingPolicyList is a list of GeneratingPolicy instances
|
||||
type GeneratingPolicyList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []GeneratingPolicy `json:"items"`
|
||||
}
|
||||
|
||||
// GeneratingPolicySpec is the specification of the desired behavior of the GeneratingPolicy.
|
||||
type GeneratingPolicySpec struct {
|
||||
// MatchConstraints specifies what resources will trigger this policy.
|
||||
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
|
||||
// Required.
|
||||
MatchConstraints *admissionregistrationv1.MatchResources `json:"matchConstraints,omitempty"`
|
||||
|
||||
// MatchConditions is a list of conditions that must be met for a request to be validated.
|
||||
// Match conditions filter requests that have already been matched by the rules,
|
||||
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
|
||||
// There are a maximum of 64 match conditions allowed.
|
||||
//
|
||||
// If a parameter object is provided, it can be accessed via the `params` handle in the same
|
||||
// manner as validation expressions.
|
||||
//
|
||||
// The exact matching logic is (in order):
|
||||
// 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
|
||||
// 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
|
||||
// 3. If any matchCondition evaluates to an error (but none are FALSE):
|
||||
// - If failurePolicy=Fail, reject the request
|
||||
// - If failurePolicy=Ignore, the policy is skipped
|
||||
//
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
|
||||
// Variables contain definitions of variables that can be used in composition of other expressions.
|
||||
// Each variable is defined as a named CEL expression.
|
||||
// The variables defined here will be available under `variables` in other expressions of the policy
|
||||
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
|
||||
//
|
||||
// The expression of a variable can refer to other variables defined earlier in the list but not those after.
|
||||
// Thus, Variables must be sorted by the order of first appearance and acyclic.
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
Variables []admissionregistrationv1.Variable `json:"variables,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
|
||||
// EvaluationConfiguration defines the configuration for the policy evaluation.
|
||||
// +optional
|
||||
EvaluationConfiguration *GeneratingPolicyEvaluationConfiguration `json:"evaluation,omitempty"`
|
||||
|
||||
// WebhookConfiguration defines the configuration for the webhook.
|
||||
// +optional
|
||||
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty"`
|
||||
|
||||
// Generation defines a set of CEL expressions that will be evaluated to generate resources.
|
||||
// Required.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
Generation []Generation `json:"generate"`
|
||||
}
|
||||
|
||||
func (s GeneratingPolicySpec) OrphanDownstreamOnPolicyDeleteEnabled() bool {
|
||||
const defaultValue = false
|
||||
if s.EvaluationConfiguration == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.EvaluationConfiguration.OrphanDownstreamOnPolicyDelete == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.EvaluationConfiguration.OrphanDownstreamOnPolicyDelete.Enabled == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return *s.EvaluationConfiguration.OrphanDownstreamOnPolicyDelete.Enabled
|
||||
}
|
||||
|
||||
func (s GeneratingPolicySpec) GenerateExistingEnabled() bool {
|
||||
const defaultValue = false
|
||||
if s.EvaluationConfiguration == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.EvaluationConfiguration.GenerateExistingConfiguration == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.EvaluationConfiguration.GenerateExistingConfiguration.Enabled == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return *s.EvaluationConfiguration.GenerateExistingConfiguration.Enabled
|
||||
}
|
||||
|
||||
func (s GeneratingPolicySpec) SynchronizationEnabled() bool {
|
||||
const defaultValue = false
|
||||
if s.EvaluationConfiguration == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.EvaluationConfiguration.SynchronizationConfiguration == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.EvaluationConfiguration.SynchronizationConfiguration.Enabled == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return *s.EvaluationConfiguration.SynchronizationConfiguration.Enabled
|
||||
}
|
||||
|
||||
func (s GeneratingPolicySpec) AdmissionEnabled() bool {
|
||||
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Admission == nil || s.EvaluationConfiguration.Admission.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
return *s.EvaluationConfiguration.Admission.Enabled
|
||||
}
|
||||
|
||||
type GeneratingPolicyEvaluationConfiguration struct {
|
||||
// Admission controls policy evaluation during admission.
|
||||
// +optional
|
||||
Admission *AdmissionConfiguration `json:"admission,omitempty"`
|
||||
|
||||
// GenerateExisting defines the configuration for generating resources for existing triggeres.
|
||||
// +optional
|
||||
GenerateExistingConfiguration *GenerateExistingConfiguration `json:"generateExisting,omitempty"`
|
||||
|
||||
// Synchronization defines the configuration for the synchronization of generated resources.
|
||||
// +optional
|
||||
SynchronizationConfiguration *SynchronizationConfiguration `json:"synchronize,omitempty"`
|
||||
|
||||
// OrphanDownstreamOnPolicyDelete defines the configuration for orphaning downstream resources on policy delete.
|
||||
OrphanDownstreamOnPolicyDelete *OrphanDownstreamOnPolicyDeleteConfiguration `json:"orphanDownstreamOnPolicyDelete,omitempty"`
|
||||
}
|
||||
|
||||
// GenerateExistingConfiguration defines the configuration for generating resources for existing triggers.
|
||||
type GenerateExistingConfiguration struct {
|
||||
// Enabled controls whether to trigger the policy for existing resources
|
||||
// If is set to "true" the policy will be triggered and applied to existing matched resources.
|
||||
// Optional. Defaults to "false" if not specified.
|
||||
// +optional
|
||||
// +kubebuilder:default=false
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// SynchronizationConfiguration defines the configuration for the synchronization of generated resources.
|
||||
type SynchronizationConfiguration struct {
|
||||
// Enabled controls if generated resources should be kept in-sync with their source resource.
|
||||
// If Synchronize is set to "true" changes to generated resources will be overwritten with resource
|
||||
// data from Data or the resource specified in the Clone declaration.
|
||||
// Optional. Defaults to "false" if not specified.
|
||||
// +optional
|
||||
// +kubebuilder:default=false
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// OrphanDownstreamOnPolicyDeleteConfiguration defines the configuration for orphaning downstream resources on policy delete.
|
||||
type OrphanDownstreamOnPolicyDeleteConfiguration struct {
|
||||
// Enabled controls whether generated resources should be deleted when the policy that generated
|
||||
// them is deleted with synchronization enabled. This option is only applicable to generate rules of the data type.
|
||||
// Optional. Defaults to "false" if not specified.
|
||||
// +optional
|
||||
// +kubebuilder:default=false
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// Generation defines the configuration for the generation of resources.
|
||||
type Generation struct {
|
||||
// Expression is a CEL expression that takes a list of resources to be generated.
|
||||
Expression string `json:"expression,omitempty"`
|
||||
}
|
||||
|
||||
type GeneratingPolicyStatus struct {
|
||||
// +optional
|
||||
ConditionStatus ConditionStatus `json:"conditionStatus,omitempty"`
|
||||
}
|
|
@ -0,0 +1,475 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=imagevalidatingpolicies,scope="Cluster",shortName=ivpol,categories=kyverno
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditionStatus.ready`
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type ImageValidatingPolicy struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec ImageValidatingPolicySpec `json:"spec"`
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status ImageValidatingPolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// BackgroundEnabled checks if background is set to true
|
||||
func (s ImageValidatingPolicy) BackgroundEnabled() bool {
|
||||
return s.Spec.BackgroundEnabled()
|
||||
}
|
||||
|
||||
type ImageValidatingPolicyStatus struct {
|
||||
// +optional
|
||||
ConditionStatus ConditionStatus `json:"conditionStatus,omitempty"`
|
||||
|
||||
// +optional
|
||||
Autogen ImageValidatingPolicyAutogenStatus `json:"autogen,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetMatchConstraints() admissionregistrationv1.MatchResources {
|
||||
if s.Spec.MatchConstraints == nil {
|
||||
return admissionregistrationv1.MatchResources{}
|
||||
}
|
||||
return *s.Spec.MatchConstraints
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetMatchConditions() []admissionregistrationv1.MatchCondition {
|
||||
return s.Spec.MatchConditions
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetWebhookConfiguration() *WebhookConfiguration {
|
||||
return s.Spec.WebhookConfiguration
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetFailurePolicy() admissionregistrationv1.FailurePolicyType {
|
||||
if s.Spec.FailurePolicy == nil {
|
||||
return admissionregistrationv1.Fail
|
||||
}
|
||||
return *s.Spec.FailurePolicy
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetVariables() []admissionregistrationv1.Variable {
|
||||
return s.Spec.Variables
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetSpec() *ImageValidatingPolicySpec {
|
||||
return &s.Spec
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetStatus() *ImageValidatingPolicyStatus {
|
||||
return &s.Status
|
||||
}
|
||||
|
||||
func (s *ImageValidatingPolicy) GetKind() string {
|
||||
return "ImageValidatingPolicy"
|
||||
}
|
||||
|
||||
// AdmissionEnabled checks if admission is set to true
|
||||
func (s ImageValidatingPolicySpec) AdmissionEnabled() bool {
|
||||
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Admission == nil || s.EvaluationConfiguration.Admission.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
return *s.EvaluationConfiguration.Admission.Enabled
|
||||
}
|
||||
|
||||
// BackgroundEnabled checks if background is set to true
|
||||
func (s ImageValidatingPolicySpec) BackgroundEnabled() bool {
|
||||
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Background == nil || s.EvaluationConfiguration.Background.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
return *s.EvaluationConfiguration.Background.Enabled
|
||||
}
|
||||
|
||||
// ValidationActions returns the validation actions.
|
||||
func (s ImageValidatingPolicySpec) ValidationActions() []admissionregistrationv1.ValidationAction {
|
||||
const defaultValue = admissionregistrationv1.Deny
|
||||
if len(s.ValidationAction) == 0 {
|
||||
return []admissionregistrationv1.ValidationAction{defaultValue}
|
||||
}
|
||||
return s.ValidationAction
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ImageValidatingPolicyList is a list of ImageValidatingPolicy instances
|
||||
type ImageValidatingPolicyList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []ImageValidatingPolicy `json:"items"`
|
||||
}
|
||||
|
||||
// CredentialsProvidersType provides the list of credential providers required.
|
||||
// +kubebuilder:validation:Enum=default;amazon;azure;google;github
|
||||
type CredentialsProvidersType string
|
||||
|
||||
const (
|
||||
DEFAULT CredentialsProvidersType = "default"
|
||||
AWS CredentialsProvidersType = "amazon"
|
||||
ACR CredentialsProvidersType = "azure"
|
||||
GCP CredentialsProvidersType = "google"
|
||||
GHCR CredentialsProvidersType = "github"
|
||||
)
|
||||
|
||||
// ImageValidatingPolicySpec is the specification of the desired behavior of the ImageValidatingPolicy.
|
||||
type ImageValidatingPolicySpec struct {
|
||||
// MatchConstraints specifies what resources this policy is designed to validate.
|
||||
// +optional
|
||||
MatchConstraints *admissionregistrationv1.MatchResources `json:"matchConstraints"`
|
||||
|
||||
// FailurePolicy defines how to handle failures for the admission policy. Failures can
|
||||
// occur from CEL expression parse errors, type check errors, runtime errors and invalid
|
||||
// or mis-configured policy definitions or bindings.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Ignore;Fail
|
||||
FailurePolicy *admissionregistrationv1.FailurePolicyType `json:"failurePolicy"`
|
||||
|
||||
// auditAnnotations contains CEL expressions which are used to produce audit
|
||||
// annotations for the audit event of the API request.
|
||||
// validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is
|
||||
// required.
|
||||
// +listType=atomic
|
||||
// +optional
|
||||
AuditAnnotations []admissionregistrationv1.AuditAnnotation `json:"auditAnnotations,omitempty"`
|
||||
|
||||
// ValidationAction specifies the action to be taken when the matched resource violates the policy.
|
||||
// Required.
|
||||
// +listType=set
|
||||
// +kubebuilder:validation:items:Enum=Deny;Audit;Warn
|
||||
ValidationAction []admissionregistrationv1.ValidationAction `json:"validationActions,omitempty"`
|
||||
|
||||
// MatchConditions is a list of conditions that must be met for a request to be validated.
|
||||
// Match conditions filter requests that have already been matched by the rules,
|
||||
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
|
||||
// There are a maximum of 64 match conditions allowed.
|
||||
// +optional
|
||||
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty"`
|
||||
|
||||
// Variables contain definitions of variables that can be used in composition of other expressions.
|
||||
// Each variable is defined as a named CEL expression.
|
||||
// +optional
|
||||
Variables []admissionregistrationv1.Variable `json:"variables,omitempty"`
|
||||
|
||||
// ValidationConfigurations defines settings for mutating and verifying image digests, and enforcing image verification through signatures.
|
||||
// +optional
|
||||
// +kubebuilder:default={}
|
||||
ValidationConfigurations ValidationConfiguration `json:"validationConfigurations"`
|
||||
|
||||
// MatchImageReferences is a list of Glob and CELExpressions to match images.
|
||||
// Any image that matches one of the rules is considered for validation
|
||||
// Any image that does not match a rule is skipped, even when they are passed as arguments to
|
||||
// image verification functions
|
||||
// +optional
|
||||
MatchImageReferences []MatchImageReference `json:"matchImageReferences"`
|
||||
|
||||
// Credentials provides credentials that will be used for authentication with registry.
|
||||
// +kubebuilder:validation:Optional
|
||||
Credentials *Credentials `json:"credentials,omitempty"`
|
||||
|
||||
// ImageExtractors is a list of CEL expression to extract images from the resource
|
||||
// +optional
|
||||
ImageExtractors []ImageExtractor `json:"images,omitempty"`
|
||||
|
||||
// Attestors provides a list of trusted authorities.
|
||||
Attestors []Attestor `json:"attestors"`
|
||||
|
||||
// Attestations provides a list of image metadata to verify
|
||||
// +optional
|
||||
Attestations []Attestation `json:"attestations"`
|
||||
|
||||
// Validations contain CEL expressions which is used to apply the image validation checks.
|
||||
// +listType=atomic
|
||||
Validations []admissionregistrationv1.Validation `json:"validations"`
|
||||
|
||||
// WebhookConfiguration defines the configuration for the webhook.
|
||||
// +optional
|
||||
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty"`
|
||||
|
||||
// EvaluationConfiguration defines the configuration for the policy evaluation.
|
||||
// +optional
|
||||
EvaluationConfiguration *EvaluationConfiguration `json:"evaluation,omitempty"`
|
||||
|
||||
// AutogenConfiguration defines the configuration for the generation controller.
|
||||
// +optional
|
||||
AutogenConfiguration *ImageValidatingPolicyAutogenConfiguration `json:"autogen,omitempty"`
|
||||
}
|
||||
|
||||
// MatchImageReference defines a Glob or a CEL expression for matching images
|
||||
// +kubebuilder:oneOf:={required:{glob}}
|
||||
// +kubebuilder:oneOf:={required:{expression}}
|
||||
type MatchImageReference struct {
|
||||
// Glob defines a globbing pattern for matching images
|
||||
// +optional
|
||||
Glob string `json:"glob,omitempty"`
|
||||
// Expression defines CEL Expressions for matching images
|
||||
// +optional
|
||||
Expression string `json:"expression,omitempty"`
|
||||
}
|
||||
|
||||
type ValidationConfiguration struct {
|
||||
// MutateDigest enables replacement of image tags with digests.
|
||||
// Defaults to true.
|
||||
// +kubebuilder:default=true
|
||||
// +optional
|
||||
MutateDigest *bool `json:"mutateDigest,omitempty"`
|
||||
|
||||
// VerifyDigest validates that images have a digest.
|
||||
// +kubebuilder:default=true
|
||||
// +optional
|
||||
VerifyDigest *bool `json:"verifyDigest,omitempty"`
|
||||
|
||||
// Required validates that images are verified, i.e., have passed a signature or attestation check.
|
||||
// +kubebuilder:default=true
|
||||
// +optional
|
||||
Required *bool `json:"required,omitempty"`
|
||||
}
|
||||
|
||||
type ImageExtractor struct {
|
||||
// Name is the name for this imageList. It is used to refer to the images in verification block as images.<name>
|
||||
Name string `json:"name"`
|
||||
|
||||
// Expression defines CEL expression to extract images from the resource.
|
||||
Expression string `json:"expression"`
|
||||
}
|
||||
|
||||
type Credentials struct {
|
||||
// AllowInsecureRegistry allows insecure access to a registry.
|
||||
// +optional
|
||||
AllowInsecureRegistry bool `json:"allowInsecureRegistry,omitempty"`
|
||||
|
||||
// Providers specifies a list of OCI Registry names, whose authentication providers are provided.
|
||||
// It can be of one of these values: default,google,azure,amazon,github.
|
||||
// +optional
|
||||
Providers []CredentialsProvidersType `json:"providers,omitempty"`
|
||||
|
||||
// Secrets specifies a list of secrets that are provided for credentials.
|
||||
// Secrets must live in the Kyverno namespace.
|
||||
// +optional
|
||||
Secrets []string `json:"secrets,omitempty"`
|
||||
}
|
||||
|
||||
// Attestor is an identity that confirms or verifies the authenticity of an image or an attestation
|
||||
// +kubebuilder:oneOf:={required:{cosign}}
|
||||
// +kubebuilder:oneOf:={required:{notary}}
|
||||
type Attestor struct {
|
||||
// Name is the name for this attestor. It is used to refer to the attestor in verification
|
||||
Name string `json:"name"`
|
||||
// Cosign defines attestor configuration for Cosign based signatures
|
||||
// +optional
|
||||
Cosign *Cosign `json:"cosign,omitempty"`
|
||||
// Notary defines attestor configuration for Notary based signatures
|
||||
// +optional
|
||||
Notary *Notary `json:"notary,omitempty"`
|
||||
}
|
||||
|
||||
// Cosign defines attestor configuration for Cosign based signatures
|
||||
type Cosign struct {
|
||||
// Key defines the type of key to validate the image.
|
||||
// +optional
|
||||
Key *Key `json:"key,omitempty"`
|
||||
// Keyless sets the configuration to verify the authority against a Fulcio instance.
|
||||
// +optional
|
||||
Keyless *Keyless `json:"keyless,omitempty"`
|
||||
// Certificate defines the configuration for local signature verification
|
||||
// +optional
|
||||
Certificate *Certificate `json:"certificate,omitempty"`
|
||||
// Sources sets the configuration to specify the sources from where to consume the signature and attestations.
|
||||
// +optional
|
||||
Source *Source `json:"source,omitempty"`
|
||||
// CTLog sets the configuration to verify the authority against a Rekor instance.
|
||||
// +optional
|
||||
CTLog *CTLog `json:"ctlog,omitempty"`
|
||||
// TUF defines the configuration to fetch sigstore root
|
||||
// +optional
|
||||
TUF *TUF `json:"tuf,omitempty"`
|
||||
// Annotations are used for image verification.
|
||||
// Every specified key-value pair must exist and match in the verified payload.
|
||||
// The payload may contain other key-value pairs.
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// StringOrExpression contains either a raw string input or a CEL expression
|
||||
// +kubebuilder:oneOf:={required:{value}}
|
||||
// +kubebuilder:oneOf:={required:{expression}}
|
||||
type StringOrExpression struct {
|
||||
// Value defines the raw string input.
|
||||
// +optional
|
||||
Value string `json:"value,omitempty"`
|
||||
// Expression defines the a CEL expression input.
|
||||
// +optional
|
||||
Expression string `json:"expression,omitempty"`
|
||||
}
|
||||
|
||||
// Notary defines attestor configuration for Notary based signatures
|
||||
type Notary struct {
|
||||
// Certs define the cert chain for Notary signature verification
|
||||
// +optional
|
||||
Certs *StringOrExpression `json:"certs,omitempty"`
|
||||
// TSACerts define the cert chain for verifying timestamps of notary signature
|
||||
// +optional
|
||||
TSACerts *StringOrExpression `json:"tsaCerts,omitempty"`
|
||||
}
|
||||
|
||||
// TUF defines the configuration to fetch sigstore root
|
||||
type TUF struct {
|
||||
// Root defines the path or data of the trusted root
|
||||
// +optional
|
||||
Root TUFRoot `json:"root,omitempty"`
|
||||
// Mirror is the base URL of Sigstore TUF repository
|
||||
// +optional
|
||||
Mirror string `json:"mirror,omitempty"`
|
||||
}
|
||||
|
||||
// TUFRoot defines the path or data of the trusted root
|
||||
type TUFRoot struct {
|
||||
// Path is the URL or File location of the TUF root
|
||||
// +optional
|
||||
Path string `json:"path,omitempty"`
|
||||
// Data is the base64 encoded TUF root
|
||||
// +optional
|
||||
Data string `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// Source specifies the location of the signature / attestations.
|
||||
type Source struct {
|
||||
// Repository defines the location from where to pull the signature / attestations.
|
||||
// +optional
|
||||
Repository string `json:"repository,omitempty"`
|
||||
// SignaturePullSecrets is an optional list of references to secrets in the
|
||||
// same namespace as the deploying resource for pulling any of the signatures
|
||||
// used by this Source.
|
||||
// +optional
|
||||
SignaturePullSecrets []corev1.LocalObjectReference `json:"PullSecrets,omitempty"`
|
||||
// TagPrefix is an optional prefix that signature and attestations have.
|
||||
// This is the 'tag based discovery' and in the future once references are
|
||||
// fully supported that should likely be the preferred way to handle these.
|
||||
// +optional
|
||||
TagPrefix string `json:"tagPrefix,omitempty"`
|
||||
}
|
||||
|
||||
// CTLog sets the configuration to verify the authority against a Rekor instance.
|
||||
type CTLog struct {
|
||||
// URL sets the url to the rekor instance (by default the public rekor.sigstore.dev)
|
||||
// +optional
|
||||
URL string `json:"url,omitempty"`
|
||||
// RekorPubKey is an optional PEM-encoded public key to use for a custom Rekor.
|
||||
// If set, this will be used to validate transparency log signatures from a custom Rekor.
|
||||
// +optional
|
||||
RekorPubKey string `json:"rekorPubKey,omitempty"`
|
||||
// CTLogPubKey, if set, is used to validate SCTs against a custom source.
|
||||
// +optional
|
||||
CTLogPubKey string `json:"ctLogPubKey,omitempty"`
|
||||
// TSACertChain, if set, is the PEM-encoded certificate chain file for the RFC3161 timestamp authority. Must
|
||||
// contain the root CA certificate. Optionally may contain intermediate CA certificates, and
|
||||
// may contain the leaf TSA certificate if not present in the timestamurce.
|
||||
// +optional
|
||||
TSACertChain string `json:"tsaCertChain,omitempty"`
|
||||
// InsecureIgnoreTlog skips transparency log verification.
|
||||
// +optional
|
||||
InsecureIgnoreTlog bool `json:"insecureIgnoreTlog,omitempty"`
|
||||
// IgnoreSCT defines whether to use the Signed Certificate Timestamp (SCT) log to check for a certificate
|
||||
// timestamp. Default is false. Set to true if this was opted out during signing.
|
||||
// +optional
|
||||
InsecureIgnoreSCT bool `json:"insecureIgnoreSCT,omitempty"`
|
||||
}
|
||||
|
||||
// A Key must specify only one of CEL, Data or KMS
|
||||
type Key struct {
|
||||
// Data contains the inline public key
|
||||
// +optional
|
||||
Data string `json:"data,omitempty"`
|
||||
// KMS contains the KMS url of the public key
|
||||
// Supported formats differ based on the KMS system used.
|
||||
// +optional
|
||||
KMS string `json:"kms,omitempty"`
|
||||
// HashAlgorithm specifues signature algorithm for public keys. Supported values are
|
||||
// sha224, sha256, sha384 and sha512. Defaults to sha256.
|
||||
// +optional
|
||||
HashAlgorithm string `json:"hashAlgorithm,omitempty"`
|
||||
// Expression is a Expression expression that returns the public key.
|
||||
// +optional
|
||||
Expression string `json:"expression,omitempty"`
|
||||
}
|
||||
|
||||
// Keyless contains location of the validating certificate and the identities
|
||||
// against which to verify.
|
||||
type Keyless struct {
|
||||
// Identities sets a list of identities.
|
||||
Identities []Identity `json:"identities"`
|
||||
// Roots is an optional set of PEM encoded trusted root certificates.
|
||||
// If not provided, the system roots are used.
|
||||
// +kubebuilder:validation:Optional
|
||||
Roots string `json:"roots,omitempty"`
|
||||
}
|
||||
|
||||
// Certificate defines the configuration for local signature verification
|
||||
type Certificate struct {
|
||||
// Certificate is the to the public certificate for local signature verification.
|
||||
// +optional
|
||||
Certificate *StringOrExpression `json:"cert,omitempty"`
|
||||
// CertificateChain is the list of CA certificates in PEM format which will be needed
|
||||
// when building the certificate chain for the signing certificate. Must start with the
|
||||
// parent intermediate CA certificate of the signing certificate and end with the root certificate
|
||||
// +optional
|
||||
CertificateChain *StringOrExpression `json:"certChain,omitempty"`
|
||||
}
|
||||
|
||||
// Identity may contain the issuer and/or the subject found in the transparency
|
||||
// log.
|
||||
// Issuer/Subject uses a strict match, while IssuerRegExp and SubjectRegExp
|
||||
// apply a regexp for matching.
|
||||
type Identity struct {
|
||||
// Issuer defines the issuer for this identity.
|
||||
// +optional
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
// Subject defines the subject for this identity.
|
||||
// +optional
|
||||
Subject string `json:"subject,omitempty"`
|
||||
// IssuerRegExp specifies a regular expression to match the issuer for this identity.
|
||||
// +optional
|
||||
IssuerRegExp string `json:"issuerRegExp,omitempty"`
|
||||
// SubjectRegExp specifies a regular expression to match the subject for this identity.
|
||||
// +optional
|
||||
SubjectRegExp string `json:"subjectRegExp,omitempty"`
|
||||
}
|
||||
|
||||
// Attestation defines the identification details of the metadata that has to be verified
|
||||
type Attestation struct {
|
||||
// Name is the name for this attestation. It is used to refer to the attestation in verification
|
||||
Name string `json:"name"`
|
||||
|
||||
// InToto defines the details of attestation attached using intoto format
|
||||
// +optional
|
||||
InToto *InToto `json:"intoto,omitempty"`
|
||||
|
||||
// Referrer defines the details of attestation attached using OCI 1.1 format
|
||||
// +optional
|
||||
Referrer *Referrer `json:"referrer,omitempty"`
|
||||
}
|
||||
|
||||
type InToto struct {
|
||||
// Type defines the type of attestation contained within the statement.
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type Referrer struct {
|
||||
// Type defines the type of attestation attached to the image.
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type ImageValidatingPolicyAutogenConfiguration struct {
|
||||
// PodControllers specifies whether to generate a pod controllers rules.
|
||||
PodControllers *PodControllersGenerationConfiguration `json:"podControllers,omitempty"`
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:path=mutatingpolicies,scope="Cluster",shortName=mpol,categories=kyverno
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditionStatus.ready`
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type MutatingPolicy struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec MutatingPolicySpec `json:"spec"`
|
||||
// Status contains policy runtime data.
|
||||
// +optional
|
||||
Status MutatingPolicyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type MutatingPolicyStatus struct {
|
||||
// +optional
|
||||
ConditionStatus ConditionStatus `json:"conditionStatus,omitempty"`
|
||||
|
||||
// +optional
|
||||
Autogen MutatingPolicyAutogenStatus `json:"autogen,omitempty"`
|
||||
|
||||
// Generated indicates whether a MutatingAdmissionPolicy is generated from the policy or not
|
||||
// +optional
|
||||
Generated bool `json:"generated"`
|
||||
}
|
||||
|
||||
// MutatingPolicySpec is the specification of the desired behavior of the MutatingPolicy.
|
||||
type MutatingPolicySpec struct {
|
||||
// MatchConstraints specifies what resources this policy is designed to evaluate.
|
||||
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
|
||||
// Required.
|
||||
MatchConstraints *admissionregistrationv1alpha1.MatchResources `json:"matchConstraints,omitempty"`
|
||||
|
||||
// failurePolicy defines how to handle failures for the admission policy. Failures can
|
||||
// occur from CEL expression parse errors, type check errors, runtime errors and invalid
|
||||
// or mis-configured policy definitions or bindings.
|
||||
//
|
||||
// failurePolicy does not define how validations that evaluate to false are handled.
|
||||
//
|
||||
// When failurePolicy is set to Fail, the validationActions field define how failures are enforced.
|
||||
//
|
||||
// Allowed values are Ignore or Fail. Defaults to Fail.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Ignore;Fail
|
||||
FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"`
|
||||
|
||||
// MatchConditions is a list of conditions that must be met for a request to be validated.
|
||||
// Match conditions filter requests that have already been matched by the rules,
|
||||
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
|
||||
// There are a maximum of 64 match conditions allowed.
|
||||
//
|
||||
// If a parameter object is provided, it can be accessed via the `params` handle in the same
|
||||
// manner as validation expressions.
|
||||
//
|
||||
// The exact matching logic is (in order):
|
||||
// 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
|
||||
// 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
|
||||
// 3. If any matchCondition evaluates to an error (but none are FALSE):
|
||||
// - If failurePolicy=Fail, reject the request
|
||||
// - If failurePolicy=Ignore, the policy is skipped
|
||||
//
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
MatchConditions []admissionregistrationv1alpha1.MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
|
||||
// Variables contain definitions of variables that can be used in composition of other expressions.
|
||||
// Each variable is defined as a named CEL expression.
|
||||
// The variables defined here will be available under `variables` in other expressions of the policy
|
||||
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
|
||||
//
|
||||
// The expression of a variable can refer to other variables defined earlier in the list but not those after.
|
||||
// Thus, Variables must be sorted by the order of first appearance and acyclic.
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
Variables []admissionregistrationv1alpha1.Variable `json:"variables,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
|
||||
// AutogenConfiguration defines the configuration for the generation controller.
|
||||
// +optional
|
||||
AutogenConfiguration *MutatingPolicyAutogenConfiguration `json:"autogen,omitempty"`
|
||||
|
||||
// TargetMatchConstraints specifies what target mutation resources this policy is designed to evaluate.
|
||||
// +optional
|
||||
TargetMatchConstraints *admissionregistrationv1alpha1.MatchResources `json:"targetMatchConstraints,omitempty"`
|
||||
|
||||
// mutations contain operations to perform on matching objects.
|
||||
// mutations may not be empty; a minimum of one mutation is required.
|
||||
// mutations are evaluated in order, and are reinvoked according to
|
||||
// the reinvocationPolicy.
|
||||
// The mutations of a policy are invoked for each binding of this policy
|
||||
// and reinvocation of mutations occurs on a per binding basis.
|
||||
//
|
||||
// +listType=atomic
|
||||
// +optional
|
||||
Mutations []admissionregistrationv1alpha1.Mutation `json:"mutations,omitempty" protobuf:"bytes,4,rep,name=mutations"`
|
||||
|
||||
// WebhookConfiguration defines the configuration for the webhook.
|
||||
// +optional
|
||||
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty"`
|
||||
|
||||
// EvaluationConfiguration defines the configuration for mutating policy evaluation.
|
||||
// +optional
|
||||
EvaluationConfiguration *MutatingPolicyEvaluationConfiguration `json:"evaluation,omitempty"`
|
||||
|
||||
// reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding
|
||||
// as part of a single admission evaluation.
|
||||
// Allowed values are "Never" and "IfNeeded".
|
||||
//
|
||||
// Never: These mutations will not be called more than once per binding in a single admission evaluation.
|
||||
//
|
||||
// IfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of
|
||||
// order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only
|
||||
// reinvoked when mutations change the object after this mutation is invoked.
|
||||
// Required.
|
||||
ReinvocationPolicy admissionregistrationv1alpha1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,7,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"`
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetMatchConstraints() admissionregistrationv1.MatchResources {
|
||||
if s.Spec.MatchConstraints == nil {
|
||||
return admissionregistrationv1.MatchResources{}
|
||||
}
|
||||
|
||||
return s.Spec.GetMatchConstraints()
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetMatchConditions() []admissionregistrationv1.MatchCondition {
|
||||
return s.Spec.GetMatchConditions()
|
||||
}
|
||||
|
||||
func (s *MutatingPolicySpec) GetMatchConstraints() admissionregistrationv1.MatchResources {
|
||||
if s.MatchConstraints == nil {
|
||||
return admissionregistrationv1.MatchResources{}
|
||||
}
|
||||
|
||||
in := s.MatchConstraints
|
||||
var out admissionregistrationv1.MatchResources
|
||||
out.NamespaceSelector = in.NamespaceSelector
|
||||
out.ObjectSelector = in.ObjectSelector
|
||||
for _, ex := range in.ExcludeResourceRules {
|
||||
out.ExcludeResourceRules = append(out.ExcludeResourceRules, admissionregistrationv1.NamedRuleWithOperations{
|
||||
ResourceNames: ex.ResourceNames,
|
||||
RuleWithOperations: ex.RuleWithOperations,
|
||||
})
|
||||
}
|
||||
for _, ex := range in.ResourceRules {
|
||||
out.ResourceRules = append(out.ResourceRules, admissionregistrationv1.NamedRuleWithOperations{
|
||||
ResourceNames: ex.ResourceNames,
|
||||
RuleWithOperations: ex.RuleWithOperations,
|
||||
})
|
||||
}
|
||||
if in.MatchPolicy != nil {
|
||||
mp := admissionregistrationv1.MatchPolicyType(*in.MatchPolicy)
|
||||
out.MatchPolicy = &mp
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *MutatingPolicySpec) SetMatchConstraints(in admissionregistrationv1.MatchResources) {
|
||||
out := &admissionregistrationv1alpha1.MatchResources{}
|
||||
out.NamespaceSelector = in.NamespaceSelector
|
||||
out.ObjectSelector = in.ObjectSelector
|
||||
for _, ex := range in.ExcludeResourceRules {
|
||||
out.ExcludeResourceRules = append(out.ExcludeResourceRules, admissionregistrationv1alpha1.NamedRuleWithOperations{
|
||||
ResourceNames: ex.ResourceNames,
|
||||
RuleWithOperations: ex.RuleWithOperations,
|
||||
})
|
||||
}
|
||||
for _, ex := range in.ResourceRules {
|
||||
out.ResourceRules = append(out.ResourceRules, admissionregistrationv1alpha1.NamedRuleWithOperations{
|
||||
ResourceNames: ex.ResourceNames,
|
||||
RuleWithOperations: ex.RuleWithOperations,
|
||||
})
|
||||
}
|
||||
if in.MatchPolicy != nil {
|
||||
mp := admissionregistrationv1alpha1.MatchPolicyType(*in.MatchPolicy)
|
||||
out.MatchPolicy = &mp
|
||||
}
|
||||
s.MatchConstraints = out
|
||||
}
|
||||
|
||||
func (s *MutatingPolicySpec) GetMatchConditions() []admissionregistrationv1.MatchCondition {
|
||||
in := s.MatchConditions
|
||||
out := make([]admissionregistrationv1.MatchCondition, len(in))
|
||||
for i := range in {
|
||||
out[i] = (admissionregistrationv1.MatchCondition)(in[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// GenerateMutatingAdmissionPolicyEnabled checks if mutating admission policy generation is enabled
|
||||
func (s MutatingPolicySpec) GenerateMutatingAdmissionPolicyEnabled() bool {
|
||||
const defaultValue = false
|
||||
if s.AutogenConfiguration == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.AutogenConfiguration.MutatingAdmissionPolicy == nil {
|
||||
return defaultValue
|
||||
}
|
||||
if s.AutogenConfiguration.MutatingAdmissionPolicy.Enabled == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return *s.AutogenConfiguration.MutatingAdmissionPolicy.Enabled
|
||||
}
|
||||
|
||||
// GetReinvocationPolicy returns the reinvocation policy of the MutatingPolicy
|
||||
func (s *MutatingPolicySpec) GetReinvocationPolicy() admissionregistrationv1alpha1.ReinvocationPolicyType {
|
||||
const defaultValue = admissionregistrationv1alpha1.NeverReinvocationPolicy
|
||||
if s.ReinvocationPolicy == "" {
|
||||
return defaultValue
|
||||
}
|
||||
return s.ReinvocationPolicy
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetFailurePolicy() admissionregistrationv1.FailurePolicyType {
|
||||
if s.Spec.FailurePolicy == nil {
|
||||
return admissionregistrationv1.Fail
|
||||
}
|
||||
return admissionregistrationv1.FailurePolicyType(*s.Spec.FailurePolicy)
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetWebhookConfiguration() *WebhookConfiguration {
|
||||
return s.Spec.WebhookConfiguration
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetVariables() []admissionregistrationv1.Variable {
|
||||
in := s.Spec.Variables
|
||||
out := make([]admissionregistrationv1.Variable, len(in))
|
||||
for i := range in {
|
||||
out[i] = (admissionregistrationv1.Variable)(in[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s MutatingPolicySpec) AdmissionEnabled() bool {
|
||||
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Admission == nil || s.EvaluationConfiguration.Admission.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
return *s.EvaluationConfiguration.Admission.Enabled
|
||||
}
|
||||
|
||||
// BackgroundEnabled checks if background is set to true
|
||||
func (s MutatingPolicySpec) BackgroundEnabled() bool {
|
||||
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Background == nil || s.EvaluationConfiguration.Background.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
return *s.EvaluationConfiguration.Background.Enabled
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetStatus() *MutatingPolicyStatus {
|
||||
return &s.Status
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetKind() string {
|
||||
return "MutatingPolicy"
|
||||
}
|
||||
|
||||
func (s *MutatingPolicy) GetSpec() *MutatingPolicySpec {
|
||||
return &s.Spec
|
||||
}
|
||||
|
||||
func (status *MutatingPolicyStatus) GetConditionStatus() *ConditionStatus {
|
||||
return &status.ConditionStatus
|
||||
}
|
||||
|
||||
type MutatingPolicyEvaluationConfiguration struct {
|
||||
EvaluationConfiguration `json:",inline"`
|
||||
|
||||
// MutateExisting controls whether existing resources are mutated.
|
||||
// +optional
|
||||
MutateExistingConfiguration *MutateExistingConfiguration `json:"mutateExisting,omitempty"`
|
||||
}
|
||||
|
||||
type MutatingPolicyAutogenConfiguration struct {
|
||||
// PodControllers specifies whether to generate a pod controllers rules.
|
||||
PodControllers *PodControllersGenerationConfiguration `json:"podControllers,omitempty"`
|
||||
// MutatingAdmissionPolicy specifies whether to generate a Kubernetes MutatingAdmissionPolicy.
|
||||
MutatingAdmissionPolicy *MAPGenerationConfiguration `json:"mutatingAdmissionPolicy,omitempty"`
|
||||
}
|
||||
|
||||
type MAPGenerationConfiguration struct {
|
||||
// Enabled specifies whether to generate a Kubernetes MutatingAdmissionPolicy.
|
||||
// Optional. Defaults to "false" if not specified.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
type MutateExistingConfiguration struct {
|
||||
// Enabled enables mutation of existing resources. Default is `false`.
|
||||
// When `spec.targetMatchConstraints` is not defined, Kyverno mutates existing resources matched in `spec.matchConstraints`.
|
||||
// +optional
|
||||
// +kubebuilder:default=false
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// MutatingPolicyList is a list of MutatingPolicy instances
|
||||
type MutatingPolicyList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []MutatingPolicy `json:"items"`
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PolicyException declares resources to be excluded from specified policies.
|
||||
type PolicyException struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec declares policy exception behaviors.
|
||||
Spec PolicyExceptionSpec `json:"spec"`
|
||||
}
|
||||
|
||||
func (p *PolicyException) GetKind() string {
|
||||
return "PolicyException"
|
||||
}
|
||||
|
||||
// Validate implements programmatic validation
|
||||
func (p *PolicyException) Validate() (errs field.ErrorList) {
|
||||
errs = append(errs, p.Spec.Validate(field.NewPath("spec"))...)
|
||||
return errs
|
||||
}
|
||||
|
||||
// PolicyExceptionSpec stores policy exception spec
|
||||
type PolicyExceptionSpec struct {
|
||||
// PolicyRefs identifies the policies to which the exception is applied.
|
||||
PolicyRefs []PolicyRef `json:"policyRefs"`
|
||||
|
||||
// MatchConditions is a list of CEL expressions that must be met for a resource to be excluded.
|
||||
// +optional
|
||||
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty"`
|
||||
}
|
||||
|
||||
// Validate implements programmatic validation
|
||||
func (p *PolicyExceptionSpec) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if len(p.PolicyRefs) == 0 {
|
||||
errs = append(errs, field.Invalid(path.Child("policyRefs"), p.PolicyRefs, "must specify at least one policy ref"))
|
||||
} else {
|
||||
for i, policyRef := range p.PolicyRefs {
|
||||
errs = append(errs, policyRef.Validate(path.Child("policyRefs").Index(i))...)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
type PolicyRef struct {
|
||||
// Name is the name of the policy
|
||||
Name string `json:"name"`
|
||||
|
||||
// Kind is the kind of the policy
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
func (p *PolicyRef) Validate(path *field.Path) (errs field.ErrorList) {
|
||||
if p.Name == "" {
|
||||
errs = append(errs, field.Invalid(path.Child("name"), p.Name, "must specify policy name"))
|
||||
}
|
||||
if p.Kind == "" {
|
||||
errs = append(errs, field.Invalid(path.Child("kind"), p.Kind, "must specify policy kind"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PolicyExceptionList is a list of Policy Exceptions
|
||||
type PolicyExceptionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []PolicyException `json:"items"`
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue