1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-04-08 10:04:25 +00:00

Merge branch 'kyverno:main' into main

This commit is contained in:
Chip Zoller 2022-10-09 10:31:19 -04:00 committed by GitHub
commit 59686f6b35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
317 changed files with 33845 additions and 37937 deletions

View file

@ -14,7 +14,6 @@ on:
- 'release*'
paths-ignore:
- 'README.md'
- 'docs/**'
- '.github/config.yml'
permissions: read-all
@ -32,7 +31,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3

View file

@ -27,7 +27,7 @@ jobs:
- uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: '1.18'
go-version: ~1.18.6
- name: Generate Code Coverage Report
run: make code-cov-report

View file

@ -35,7 +35,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Set up Helm
uses: azure/setup-helm@18bc76811624f360dbd7f18c2d4ecb32c7b87bab # v1.1

View file

@ -34,7 +34,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Set up Helm
uses: azure/setup-helm@18bc76811624f360dbd7f18c2d4ecb32c7b87bab # v1.1

View file

@ -16,7 +16,7 @@ jobs:
- uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: "^1.18.x"
go-version: ~1.18.6
- name: run FOSSA analysis
env:

View file

@ -53,6 +53,12 @@ jobs:
if [[ "$RELEASE_VERSION" = "kyverno-chart-v"* ]]; then
cp -a charts/kyverno charts-tmp/kyverno
fi
if [[ "$RELEASE_VERSION" = "kyverno-policies-chart-"* ]]; then
cp -a charts/kyverno-policies charts-tmp/kyverno-policies
fi
if [[ "$RELEASE_VERSION" = "kyverno-chart-"* ]]; then
cp -a charts/kyverno charts-tmp/kyverno
fi
- name: Run chart-releaser
uses: stefanprodan/helm-gh-pages@b43a8719cc63fdb3aa943cc57359ab19118eab3f #v1.5.0
@ -70,6 +76,6 @@ jobs:
for dir in `find charts-tmp -maxdepth 1 -mindepth 1 -type d -print`; do
chart=${dir##*/}
echo "Found chart: ${chart}"
helm package charts-tmp/${chart} --destination dist
helm push dist/${chart}-*.tgz oci://ghcr.io/${GITHUB_REPOSITORY}
done
helm package charts-tmp/${chart} --destination .dist
helm push .dist/${chart}-*.tgz oci://ghcr.io/${{ github.repository_owner }}/charts
done

View file

@ -23,7 +23,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3
@ -75,7 +75,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3
@ -103,7 +103,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3
@ -140,7 +140,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3

19
.github/workflows/nancy.yaml vendored Normal file
View file

@ -0,0 +1,19 @@
name: Nancy
on:
push:
branches:
- 'main'
- 'release*'
jobs:
nancy:
runs-on: ubuntu-latest
name: Nancy
steps:
- name: Checkout
uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2
- name: WriteGoList
run: go list -json -m all > go.list
- name: Nancy SAST Scan
uses: sonatype-nexus-community/nancy-github-action@aae196481b961d446f4bff9012e4e3b63d7921a4 # pin@main

View file

@ -62,14 +62,14 @@ jobs:
run: echo ::set-output name=version::${GITHUB_REF#refs/*/}
- name: Checkout
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # pin@v2.4.0
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # pin@v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3
@ -80,8 +80,8 @@ jobs:
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- uses: creekorful/goreportcard-action@1f35ced8cdac2cba28c9a2f2288a16aacfd507f9 # v1.0
- uses: creekorful/goreportcard-action@1f35ced8cdac2cba28c9a2f2288a16aacfd507f9 # pin@v1.0
- name: Make Release
env:
@ -91,22 +91,33 @@ jobs:
mkdir release
make release-notes > release/release-notes.out
cat release/release-notes.out
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@5df302e5e9e4c66310a6b6493a8865b12c555af2 #v2.8.0
uses: goreleaser/goreleaser-action@5df302e5e9e4c66310a6b6493a8865b12c555af2 # pin@v2.8.0
with:
version: latest
args: release --rm-dist --debug --release-notes=release/release-notes.out
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build yaml manifest
run: make codegen-release
- name: Upload yaml manifest
uses: svenstaro/upload-release-action@133984371c30d34e38222a64855679a414cb7575 # pin@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: config/.release/install.yaml
asset_name: install.yaml
tag: ${{ github.ref }}
release-cli-via-krew:
runs-on: ubuntu-latest
needs:
- create-release
needs:
- create-release
steps:
- name: Checkout
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # pin@v2.4.0
- name: Unshallow
run: git fetch --prune --unshallow
@ -120,4 +131,4 @@ jobs:
- name: Update new version in krew-index
if: steps.check-tag.outputs.match == 'true'
uses: rajatjindal/krew-release-bot@3320c0b546b5d2320613c46762bd3f73e2801bdc # v0.0.38
uses: rajatjindal/krew-release-bot@3320c0b546b5d2320613c46762bd3f73e2801bdc # pin@v0.0.38

View file

@ -44,7 +44,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Install Cosign
uses: sigstore/cosign-installer@116dc6872c0a067bcb78758f18955414cdbf918f # v1.4.1
@ -109,20 +109,25 @@ jobs:
id: ko-publish-dev
if: ${{inputs.tag == 'image' && steps.extract_branch.outputs.branch == 'main'}}
run: |
echo "::set-output name=digest::$(REGISTRY=ghcr.io REGISTRY_PASSWORD=${{secrets.registry_password}} make ${{inputs.publish_command}}-dev)"
set -e
echo "::set-output name=digest::$(REGISTRY=ghcr.io REPO=${{ github.repository_owner }} REGISTRY_PASSWORD=${{secrets.registry_password}} make ${{inputs.publish_command}}-dev)"
- name: ko build release image
id: ko-publish
env:
COSIGN_REPOSITORY: "ghcr.io/${{ github.repository_owner }}/sbom"
if: ${{inputs.tag == 'release' || (inputs.tag == 'image' && steps.check-branch.outputs.match == 'true')}}
run: |
echo "::set-output name=digest::$(REGISTRY=ghcr.io REGISTRY_PASSWORD=${{secrets.registry_password}} make ${{inputs.publish_command}})"
set -e
echo "::set-output name=digest::$(REGISTRY=ghcr.io REPO=${{ github.repository_owner }} REGISTRY_PASSWORD=${{secrets.registry_password}} make ${{inputs.publish_command}})"
- name: Sign dev image
if: ${{inputs.tag == 'image' && steps.extract_branch.outputs.branch == 'main'}}
env:
COSIGN_EXPERIMENTAL: "true"
COSIGN_REPOSITORY: "ghcr.io/${{ github.repository_owner }}/signatures"
run: |
run: |
set -e
cosign sign \
-a "repo=${{ github.repository }}" \
-a "workflow=${{ github.workflow }}" \
@ -134,7 +139,8 @@ jobs:
env:
COSIGN_EXPERIMENTAL: "true"
COSIGN_REPOSITORY: "ghcr.io/${{ github.repository_owner }}/signatures"
run: |
run: |
set -e
cosign sign \
-a "repo=${{ github.repository }}" \
-a "workflow=${{ github.workflow }}" \

21
.github/workflows/sonarcloud.yaml vendored Normal file
View file

@ -0,0 +1,21 @@
name: Sonarcloud workflow
on:
push:
branches:
- 'main'
- 'release*'
jobs:
sonarcloud:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
- name: SonarCloud Scan
uses: sonarsource/sonarcloud-github-action@156db6fef3e168e4972abb76de0b32bbce8ec77a # pin@master
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

View file

@ -31,7 +31,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f # pin@v3
with:
go-version: 1.18
go-version: ~1.18.6
- name: golangci-lint
uses: golangci/golangci-lint-action@537aa1903e5d359d0b27dbc19ddd22c5087f3fbc # pin@v3
@ -84,7 +84,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # pin@v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3

View file

@ -23,7 +23,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: 1.18
go-version: ~1.18.6
- name: Set up Helm
uses: azure/setup-helm@18bc76811624f360dbd7f18c2d4ecb32c7b87bab # v1.1

3
.gitignore vendored
View file

@ -12,3 +12,6 @@ kubectl-kyverno
.DS_Store
.tools
.gopath
/config/.helm
/config/.release
.dist

View file

@ -1,3 +1,14 @@
## v1.8.0-rc3
### Note
- A new flag `backgroundScan` to enable/disable kyverno background scans (default value is `true`). When this is set to `false`, kyverno will not perform background scans and won't trigger continuous evaluation of policies.
- A new flag `admissionReports` to enable/disable kyverno admission reports (default value is `true`). When this is set to `false`, kyverno will not create admission reports.
- If both `backgroundScan` and `admissionReports` are set to `false` the entire reports system will be disabled.
- A new flag `reportsChunkSize` to split reports according to the number of results contained in the report (default value is `1000`). This can be disabled by setting the flag value to `0`.
- Deprecated `splitPolicyReport` flag, splitting reports per policy is always enabled, keeping it for backward compatibility, will be removed in future version.
- `ReportChangeRequest` and `ClusterReportChangeRequest` CRDs have been removed and replaced by `AdmissionReport`, `ClusterAdmissionReport`, `BackgroundScanReport` and `ClusterBackgroundScanReport` CRDs.
## v1.8.0-rc1
### Note

346
Makefile
View file

@ -11,18 +11,23 @@ GIT_HASH := $(GIT_BRANCH)/$(shell git log -1 --pretty=format:"%H")
TIMESTAMP := $(shell date '+%Y-%m-%d_%I:%M:%S%p')
VERSION ?= $(shell git describe --match "v[0-9]*")
REGISTRY ?= ghcr.io
REPO = $(REGISTRY)/kyverno
REPO ?= kyverno
IMAGE_TAG_LATEST_DEV = $(shell git describe --match "[0-9].[0-9]-dev*" | cut -d '-' -f-2)
IMAGE_TAG_DEV = $(GIT_VERSION_DEV)
IMAGE_TAG ?= $(GIT_VERSION)
K8S_VERSION ?= $(shell kubectl version --short | grep -i server | cut -d" " -f3 | cut -c2-)
TEST_GIT_BRANCH ?= main
KIND_IMAGE ?= kindest/node:v1.24.4
KIND_NAME ?= kind
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
KOCACHE ?= /tmp/ko-cache
BUILD_WITH ?= ko
KYVERNOPRE_IMAGE := kyvernopre
KYVERNO_IMAGE := kyverno
CLI_IMAGE := kyverno-cli
REPO_KYVERNOPRE := $(REGISTRY)/$(REPO)/$(KYVERNOPRE_IMAGE)
REPO_KYVERNO := $(REGISTRY)/$(REPO)/$(KYVERNO_IMAGE)
REPO_CLI := $(REGISTRY)/$(REPO)/$(CLI_IMAGE)
#########
# TOOLS #
@ -36,7 +41,8 @@ CONTROLLER_GEN_VERSION := v0.9.1-0.20220629131006-1878064c4cdf
CLIENT_GEN := $(TOOLS_DIR)/client-gen
LISTER_GEN := $(TOOLS_DIR)/lister-gen
INFORMER_GEN := $(TOOLS_DIR)/informer-gen
CODE_GEN_VERSION := v0.19.0
OPENAPI_GEN := $(TOOLS_DIR)/openapi-gen
CODE_GEN_VERSION := v0.25.2
GEN_CRD_API_REFERENCE_DOCS := $(TOOLS_DIR)/gen-crd-api-reference-docs
GEN_CRD_API_REFERENCE_DOCS_VERSION := latest
GO_ACC := $(TOOLS_DIR)/go-acc
@ -48,8 +54,8 @@ GOIMPORTS_VERSION := latest
HELM_DOCS := $(TOOLS_DIR)/helm-docs
HELM_DOCS_VERSION := v1.11.0
KO := $(TOOLS_DIR)/ko
KO_VERSION := v0.12.0
TOOLS := $(KIND) $(CONTROLLER_GEN) $(CLIENT_GEN) $(LISTER_GEN) $(INFORMER_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM_DOCS) $(KO)
KO_VERSION := main #e93dbee8540f28c45ec9a2b8aec5ef8e43123966
TOOLS := $(KIND) $(CONTROLLER_GEN) $(CLIENT_GEN) $(LISTER_GEN) $(INFORMER_GEN) $(OPENAPI_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM_DOCS) $(KO)
ifeq ($(GOOS), darwin)
SED := gsed
else
@ -57,36 +63,51 @@ SED := sed
endif
$(KIND):
@echo Install kind... >&2
@GOBIN=$(TOOLS_DIR) go install sigs.k8s.io/kind@$(KIND_VERSION)
$(CONTROLLER_GEN):
@echo Install controller-gen... >&2
@GOBIN=$(TOOLS_DIR) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION)
$(CLIENT_GEN):
@echo Install client-gen... >&2
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/client-gen@$(CODE_GEN_VERSION)
$(LISTER_GEN):
@echo Install lister-gen... >&2
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/lister-gen@$(CODE_GEN_VERSION)
$(INFORMER_GEN):
@echo Install informer-gen... >&2
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/informer-gen@$(CODE_GEN_VERSION)
$(OPENAPI_GEN):
@echo Install openapi-gen... >&2
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/openapi-gen@$(CODE_GEN_VERSION)
$(GEN_CRD_API_REFERENCE_DOCS):
@echo Install gen-crd-api-reference-docs... >&2
@GOBIN=$(TOOLS_DIR) go install github.com/ahmetb/gen-crd-api-reference-docs@$(GEN_CRD_API_REFERENCE_DOCS_VERSION)
$(GO_ACC):
@echo Install go-acc... >&2
@GOBIN=$(TOOLS_DIR) go install github.com/ory/go-acc@$(GO_ACC_VERSION)
$(KUSTOMIZE):
@echo Install kustomize... >&2
@GOBIN=$(TOOLS_DIR) go install sigs.k8s.io/kustomize/kustomize/v4@$(KUSTOMIZE_VERSION)
$(GOIMPORTS):
@echo Install goimports... >&2
@GOBIN=$(TOOLS_DIR) go install golang.org/x/tools/cmd/goimports@$(GOIMPORTS_VERSION)
$(HELM_DOCS):
@echo Install helm-docs... >&2
@GOBIN=$(TOOLS_DIR) go install github.com/norwoodj/helm-docs/cmd/helm-docs@$(HELM_DOCS_VERSION)
$(KO):
@echo Install ko... >&2
@GOBIN=$(TOOLS_DIR) go install github.com/google/ko@$(KO_VERSION)
.PHONY: install-tools
@ -94,6 +115,7 @@ install-tools: $(TOOLS) ## Install tools
.PHONY: clean-tools
clean-tools: ## Remove installed tools
@echo Clean tools... >&2
@rm -rf $(TOOLS_DIR)
#################
@ -114,12 +136,12 @@ LD_FLAGS_DEV = "-s -w -X $(PACKAGE)/pkg/version.BuildVersion=$(GIT_VERSION_DE
.PHONY: fmt
fmt: ## Run go fmt
@echo Go fmt...
@echo Go fmt... >&2
@go fmt ./...
.PHONY: vet
vet: ## Run go vet
@echo Go vet...
@echo Go vet... >&2
@go vet ./...
.PHONY: unused-package-check
@ -130,15 +152,15 @@ unused-package-check:
fi
$(KYVERNOPRE_BIN): fmt vet
@echo Build kyvernopre binary...
@echo Build kyvernopre binary... >&2
@CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) go build -o $(KYVERNOPRE_BIN) -ldflags=$(LD_FLAGS) $(KYVERNOPRE_DIR)
$(KYVERNO_BIN): fmt vet
@echo Build kyverno binary...
@echo Build kyverno binary... >&2
@CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) go build -o $(KYVERNO_BIN) -ldflags=$(LD_FLAGS) $(KYVERNO_DIR)
$(CLI_BIN): fmt vet
@echo Build cli binary...
@echo Build cli binary... >&2
@CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) go build -o $(CLI_BIN) -ldflags=$(LD_FLAGS) $(CLI_DIR)
.PHONY: build-kyvernopre
@ -160,23 +182,20 @@ PLATFORMS := linux/amd64,linux/arm64,linux/s390x
LOCAL_PLATFORM := linux/$(GOARCH)
KO_TAGS := latest,$(IMAGE_TAG)
KO_TAGS_DEV := latest,$(IMAGE_TAG_DEV)
KYVERNOPRE_IMAGE := kyvernopre
KYVERNO_IMAGE := kyverno
CLI_IMAGE := kyverno-cli
.PHONY: ko-build-kyvernopre
ko-build-kyvernopre: $(KO) ## Build kyvernopre local image (with ko)
@echo Build kyvernopre local image with ko...
@echo Build kyvernopre local image with ko... >&2
@LD_FLAGS=$(LD_FLAGS_DEV) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=ko.local $(KO) build $(KYVERNOPRE_DIR) --preserve-import-paths --tags=$(KO_TAGS_DEV) --platform=$(LOCAL_PLATFORM)
.PHONY: ko-build-kyverno
ko-build-kyverno: $(KO) ## Build kyverno local image (with ko)
@echo Build kyverno local image with ko...
@echo Build kyverno local image with ko... >&2
@LD_FLAGS=$(LD_FLAGS_DEV) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=ko.local $(KO) build $(KYVERNO_DIR) --preserve-import-paths --tags=$(KO_TAGS_DEV) --platform=$(LOCAL_PLATFORM)
.PHONY: ko-build-cli
ko-build-cli: $(KO) ## Build cli local image (with ko)
@echo Build cli local image with ko...
@echo Build cli local image with ko... >&2
@LD_FLAGS=$(LD_FLAGS_DEV) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=ko.local $(KO) build $(CLI_DIR) --preserve-import-paths --tags=$(KO_TAGS_DEV) --platform=$(LOCAL_PLATFORM)
.PHONY: ko-build-all
@ -186,9 +205,6 @@ ko-build-all: ko-build-kyvernopre ko-build-kyverno ko-build-cli ## Build all loc
# PUBLISH (KO) #
################
REPO_KYVERNOPRE := $(REPO)/$(KYVERNOPRE_IMAGE)
REPO_KYVERNO := $(REPO)/$(KYVERNO_IMAGE)
REPO_CLI := $(REPO)/$(CLI_IMAGE)
REGISTRY_USERNAME ?= dummy
KO_KYVERNOPRE_IMAGE := ko.local/github.com/kyverno/kyverno/cmd/initcontainer
KO_KYVERNO_IMAGE := ko.local/github.com/kyverno/kyverno/cmd/kyverno
@ -233,19 +249,19 @@ ko-publish-all-dev: ko-publish-kyvernopre-dev ko-publish-kyverno-dev ko-publish-
.PHONY: docker-get-kyvernopre-digest
docker-get-kyvernopre-digest: ## Get kyvernopre image digest (with docker)
@docker buildx imagetools inspect --raw $(REPO)/$(KYVERNOPRE_IMAGE):$(IMAGE_TAG) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
@docker buildx imagetools inspect --raw $(REPO_KYVERNOPRE):$(IMAGE_TAG) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
.PHONY: docker-get-kyvernopre-digest-dev
docker-get-kyvernopre-digest-dev: ## Get kyvernopre dev image digest (with docker)
@docker buildx imagetools inspect --raw $(REPO)/$(KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
@docker buildx imagetools inspect --raw $(REPO_KYVERNOPRE):$(IMAGE_TAG_DEV) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
.PHONY: docker-get-kyverno-digest
docker-get-kyverno-digest: ## Get kyverno image digest (with docker)
@docker buildx imagetools inspect --raw $(REPO)/$(KYVERNO_IMAGE):$(IMAGE_TAG) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
@docker buildx imagetools inspect --raw $(REPO_KYVERNO):$(IMAGE_TAG) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
.PHONY: docker-get-kyverno-digest-dev
docker-get-kyverno-digest-dev: ## Get kyverno dev image digest (with docker)
@docker buildx imagetools inspect --raw $(REPO)/$(KYVERNO_IMAGE):$(IMAGE_TAG_DEV) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
@docker buildx imagetools inspect --raw $(REPO_KYVERNO):$(IMAGE_TAG_DEV) | perl -pe 'chomp if eof' | openssl dgst -sha256 | sed 's/^.* //'
.PHONY: docker-buildx-builder
docker-buildx-builder:
@ -257,23 +273,23 @@ docker-buildx-builder:
# BUILD (DOCKER) #
##################
DOCKER_KYVERNOPRE_IMAGE := $(REPO)/$(KYVERNOPRE_IMAGE)
DOCKER_KYVERNO_IMAGE := $(REPO)/$(KYVERNO_IMAGE)
DOCKER_KYVERNOPRE_IMAGE := $(REPO_KYVERNOPRE)
DOCKER_KYVERNO_IMAGE := $(REPO_KYVERNO)
.PHONY: docker-build-kyvernopre
docker-build-kyvernopre: docker-buildx-builder ## Build kyvernopre local image (with docker)
@echo Build kyvernopre local image with docker...
@docker buildx build --file $(KYVERNOPRE_DIR)/Dockerfile --progress plain --load --platform $(LOCAL_PLATFORM) --tag $(REPO)/$(KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV) . --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
@echo Build kyvernopre local image with docker... >&2
@docker buildx build --file $(KYVERNOPRE_DIR)/Dockerfile --progress plain --load --platform $(LOCAL_PLATFORM) --tag $(REPO_KYVERNOPRE):$(IMAGE_TAG_DEV) . --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
.PHONY: docker-build-kyverno
docker-build-kyverno: docker-buildx-builder ## Build kyverno local image (with docker)
@echo Build kyverno local image with docker...
@docker buildx build --file $(KYVERNO_DIR)/Dockerfile --progress plain --load --platform $(LOCAL_PLATFORM) --tag $(REPO)/$(KYVERNO_IMAGE):$(IMAGE_TAG_DEV) . --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
@echo Build kyverno local image with docker... >&2
@docker buildx build --file $(KYVERNO_DIR)/Dockerfile --progress plain --load --platform $(LOCAL_PLATFORM) --tag $(REPO_KYVERNO):$(IMAGE_TAG_DEV) . --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
.PHONY: docker-build-cli
docker-build-cli: docker-buildx-builder ## Build cli local image (with docker)
@echo Build cli local image with docker...
@docker buildx build --file $(CLI_DIR)/Dockerfile --progress plain --load --platform $(LOCAL_PLATFORM) --tag $(REPO)/$(CLI_IMAGE):$(IMAGE_TAG_DEV) . --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
@echo Build cli local image with docker... >&2
@docker buildx build --file $(CLI_DIR)/Dockerfile --progress plain --load --platform $(LOCAL_PLATFORM) --tag $(REPO_CLI):$(IMAGE_TAG_DEV) . --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
.PHONY: docker-build-all
docker-build-all: docker-build-kyvernopre docker-build-kyverno docker-build-cli ## Build all local images (with docker)
@ -284,32 +300,32 @@ docker-build-all: docker-build-kyvernopre docker-build-kyverno docker-build-cli
.PHONY: docker-publish-kyvernopre
docker-publish-kyvernopre: docker-buildx-builder ## Build and publish kyvernopre image (with docker)
@docker buildx build --file $(KYVERNOPRE_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) --tag $(REPO)/$(KYVERNOPRE_IMAGE):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
@docker buildx build --file $(KYVERNOPRE_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) --tag $(REPO_KYVERNOPRE):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
.PHONY: docker-publish-kyvernopre-dev
docker-publish-kyvernopre-dev: docker-buildx-builder ## Build and publish kyvernopre dev image (with docker)
@docker buildx build --file $(KYVERNOPRE_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) \
--tag $(REPO)/$(KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV) --tag $(REPO)/$(KYVERNOPRE_IMAGE):$(IMAGE_TAG_LATEST_DEV)-latest --tag $(REPO)/$(KYVERNOPRE_IMAGE):latest \
--tag $(REPO_KYVERNOPRE):$(IMAGE_TAG_DEV) --tag $(REPO_KYVERNOPRE):$(IMAGE_TAG_LATEST_DEV)-latest --tag $(REPO_KYVERNOPRE):latest \
. --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
.PHONY: docker-publish-kyverno
docker-publish-kyverno: docker-buildx-builder ## Build and publish kyverno image (with docker)
@docker buildx build --file $(KYVERNO_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) --tag $(REPO)/$(KYVERNO_IMAGE):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
@docker buildx build --file $(KYVERNO_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) --tag $(REPO_KYVERNO):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
.PHONY: docker-publish-kyverno-dev
docker-publish-kyverno-dev: docker-buildx-builder ## Build and publish kyverno dev image (with docker)
@docker buildx build --file $(KYVERNO_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) \
--tag $(REPO)/$(KYVERNO_IMAGE):$(IMAGE_TAG_DEV) --tag $(REPO)/$(KYVERNO_IMAGE):$(IMAGE_TAG_LATEST_DEV)-latest --tag $(REPO)/$(KYVERNO_IMAGE):latest \
--tag $(REPO_KYVERNO):$(IMAGE_TAG_DEV) --tag $(REPO_KYVERNO):$(IMAGE_TAG_LATEST_DEV)-latest --tag $(REPO_KYVERNO):latest \
. --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
.PHONY: docker-publish-cli
docker-publish-cli: docker-buildx-builder ## Build and publish cli image (with docker)
@docker buildx build --file $(CLI_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) --tag $(REPO)/$(CLI_IMAGE):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
@docker buildx build --file $(CLI_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) --tag $(REPO_CLI):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
.PHONY: docker-publish-cli-dev
docker-publish-cli-dev: docker-buildx-builder ## Build and publish cli dev image (with docker)
@docker buildx build --file $(CLI_DIR)/Dockerfile --progress plain --push --platform $(PLATFORMS) \
--tag $(REPO)/$(CLI_IMAGE):$(IMAGE_TAG_DEV) --tag $(REPO)/$(CLI_IMAGE):$(IMAGE_TAG_LATEST_DEV)-latest --tag $(REPO)/$(CLI_IMAGE):latest \
--tag $(REPO_CLI):$(IMAGE_TAG_DEV) --tag $(REPO_CLI):$(IMAGE_TAG_LATEST_DEV)-latest --tag $(REPO_CLI):latest \
. --build-arg LD_FLAGS=$(LD_FLAGS_DEV)
.PHONY: docker-publish-all
@ -350,27 +366,27 @@ LISTERS_PACKAGE := $(OUT_PACKAGE)/listers
INFORMERS_PACKAGE := $(OUT_PACKAGE)/informers
$(GOPATH_SHIM):
@echo Create gopath shim...
@echo Create gopath shim... >&2
@mkdir -p $(GOPATH_SHIM)
.INTERMEDIATE: $(PACKAGE_SHIM)
$(PACKAGE_SHIM): $(GOPATH_SHIM)
@echo Create package shim...
@echo Create package shim... >&2
@mkdir -p $(GOPATH_SHIM)/src/github.com/kyverno && ln -s -f ${PWD} $(PACKAGE_SHIM)
.PHONY: codegen-client-clientset
codegen-client-clientset: $(PACKAGE_SHIM) $(CLIENT_GEN) ## Generate clientset
@echo Generate clientset...
@echo Generate clientset... >&2
@GOPATH=$(GOPATH_SHIM) $(CLIENT_GEN) --go-header-file ./scripts/boilerplate.go.txt --clientset-name versioned --output-package $(CLIENTSET_PACKAGE) --input-base "" --input $(INPUT_DIRS)
.PHONY: codegen-client-listers
codegen-client-listers: $(PACKAGE_SHIM) $(LISTER_GEN) ## Generate listers
@echo Generate listers...
@echo Generate listers... >&2
@GOPATH=$(GOPATH_SHIM) $(LISTER_GEN) --go-header-file ./scripts/boilerplate.go.txt --output-package $(LISTERS_PACKAGE) --input-dirs $(INPUT_DIRS)
.PHONY: codegen-client-informers
codegen-client-informers: $(PACKAGE_SHIM) $(INFORMER_GEN) ## Generate informers
@echo Generate informers...
@echo Generate informers... >&2
@GOPATH=$(GOPATH_SHIM) $(INFORMER_GEN) --go-header-file ./scripts/boilerplate.go.txt --output-package $(INFORMERS_PACKAGE) --input-dirs $(INPUT_DIRS) --versioned-clientset-package $(CLIENTSET_PACKAGE)/versioned --listers-package $(LISTERS_PACKAGE)
.PHONY: codegen-client-all
@ -378,12 +394,12 @@ codegen-client-all: codegen-client-clientset codegen-client-listers codegen-clie
.PHONY: codegen-crds-kyverno
codegen-crds-kyverno: $(CONTROLLER_GEN) ## Generate kyverno CRDs
@echo Generate kyverno crds...
@echo Generate kyverno crds... >&2
@$(CONTROLLER_GEN) crd paths=./api/kyverno/... crd:crdVersions=v1 output:dir=./config/crds
.PHONY: codegen-crds-report
codegen-crds-report: $(CONTROLLER_GEN) ## Generate policy reports CRDs
@echo Generate policy reports crds...
@echo Generate policy reports crds... >&2
@$(CONTROLLER_GEN) crd paths=./api/policyreport/... crd:crdVersions=v1 output:dir=./config/crds
.PHONY: codegen-crds-all
@ -391,12 +407,12 @@ codegen-crds-all: codegen-crds-kyverno codegen-crds-report ## Generate all CRDs
.PHONY: codegen-deepcopy-kyverno
codegen-deepcopy-kyverno: $(CONTROLLER_GEN) $(GOIMPORTS) ## Generate kyverno deep copy functions
@echo Generate kyverno deep copy functions...
@echo Generate kyverno deep copy functions... >&2
@$(CONTROLLER_GEN) object:headerFile="scripts/boilerplate.go.txt" paths="./api/kyverno/..." && $(GOIMPORTS) -w ./api/kyverno
.PHONY: codegen-deepcopy-report
codegen-deepcopy-report: $(CONTROLLER_GEN) $(GOIMPORTS) ## Generate policy reports deep copy functions
@echo Generate policy reports deep copy functions...
@echo Generate policy reports deep copy functions... >&2
@$(CONTROLLER_GEN) object:headerFile="scripts/boilerplate.go.txt" paths="./api/policyreport/..." && $(GOIMPORTS) -w ./api/policyreport
.PHONY: codegen-deepcopy-all
@ -404,7 +420,7 @@ codegen-deepcopy-all: codegen-deepcopy-kyverno codegen-deepcopy-report ## Genera
.PHONY: codegen-api-docs
codegen-api-docs: $(PACKAGE_SHIM) $(GEN_CRD_API_REFERENCE_DOCS) ## Generate API docs
@echo Generate api docs...
@echo Generate api docs... >&2
@rm -rf docs/crd && mkdir -p docs/crd
@GOPATH=$(GOPATH_SHIM) $(GEN_CRD_API_REFERENCE_DOCS) -v 6 -api-dir ./api/kyverno/v1alpha2 -config docs/config.json -template-dir docs/template -out-file docs/crd/v1alpha2/index.html
@GOPATH=$(GOPATH_SHIM) $(GEN_CRD_API_REFERENCE_DOCS) -v 6 -api-dir ./api/kyverno/v1beta1 -config docs/config.json -template-dir docs/template -out-file docs/crd/v1beta1/index.html
@ -413,19 +429,60 @@ codegen-api-docs: $(PACKAGE_SHIM) $(GEN_CRD_API_REFERENCE_DOCS) ## Generate API
.PHONY: codegen-helm-docs
codegen-helm-docs: ## Generate helm docs
@echo Generate helm docs...
@docker run -v ${PWD}:/work -w /work jnorwood/helm-docs:v1.11.0 -s file
@echo Generate helm docs... >&2
@docker run -v ${PWD}/charts:/work -w /work jnorwood/helm-docs:v1.11.0 -s file
.PHONY: codegen-helm-crds
codegen-helm-crds: $(KUSTOMIZE) codegen-crds-all ## Generate helm CRDs
@echo Generate helm crds...
@$(KUSTOMIZE) build ./config/release | $(KUSTOMIZE) cfg grep kind=CustomResourceDefinition | $(SED) -e "1i{{- if .Values.installCRDs }}" -e '$$a{{- end }}' > ./charts/kyverno/templates/crds.yaml
@echo Create temp folder for kustomization... >&2
@mkdir -p config/.helm
@echo Create kustomization... >&2
@VERSION='"{{.Chart.AppVersion}}"' TOP_PATH=".." envsubst < config/templates/labels.yaml.envsubst > config/.helm/labels.yaml
@VERSION=dummy TOP_PATH=".." envsubst < config/templates/kustomization.yaml.envsubst > config/.helm/kustomization.yaml
@echo Generate helm crds... >&2
@$(KUSTOMIZE) build ./config/.helm | $(KUSTOMIZE) cfg grep kind=CustomResourceDefinition | $(SED) -e "1i{{- if .Values.installCRDs }}" -e '$$a{{- end }}' > ./charts/kyverno/templates/crds.yaml
.PHONY: codegen-helm-all
codegen-helm-all: codegen-helm-crds codegen-helm-docs ## Generate helm docs and CRDs
.PHONY: codegen-install
codegen-install: $(KUSTOMIZE) ## Create install maifests
@echo Create kustomization... >&2
@VERSION=latest TOP_PATH="." envsubst < config/templates/labels.yaml.envsubst > config/labels.yaml
@VERSION=latest TOP_PATH="." envsubst < config/templates/kustomization.yaml.envsubst > config/kustomization.yaml
@echo Generate install.yaml... >&2
@$(KUSTOMIZE) build ./config > ./config/install.yaml
@echo Generate install_debug.yaml... >&2
@$(KUSTOMIZE) build ./config/debug > ./config/install_debug.yaml
# guidance https://github.com/kyverno/kyverno/wiki/Generate-a-Release
.PHONY: codegen-release
codegen-release: codegen-install $(KUSTOMIZE) ## Create release maifests
@echo Create release folder... >&2
@mkdir -p config/.release
@echo Create kustomization... >&2
@VERSION=$(GIT_VERSION) TOP_PATH=".." envsubst < config/templates/labels.yaml.envsubst > config/.release/labels.yaml
@VERSION=$(GIT_VERSION) TOP_PATH=".." envsubst < config/templates/kustomization.yaml.envsubst > config/.release/kustomization.yaml
@echo Generate release manifests... >&2
@$(KUSTOMIZE) build ./config/.release > ./config/.release/install.yaml
.PHONY: codegen-quick
codegen-quick: codegen-deepcopy-all codegen-crds-all codegen-api-docs codegen-helm-all codegen-install codegen-release ## Generate all generated code except client
.PHONY: codegen-slow
codegen-slow: codegen-client-all ## Generate client code
.PHONY: codegen-all
codegen-all: codegen-deepcopy-all codegen-crds-all codegen-client-all codegen-api-docs codegen-helm-all ## Generate all generated code
codegen-all: codegen-quick codegen-slow ## Generate all generated code
# .PHONY: codegen-openapi
# codegen-openapi: $(PACKAGE_SHIM) $(OPENAPI_GEN) ## Generate open api code
# @echo Generate open api definitions... >&2
# @GOPATH=$(GOPATH_SHIM) $(OPENAPI_GEN) --go-header-file ./scripts/boilerplate.go.txt \
# --input-dirs $(INPUT_DIRS) \
# --input-dirs k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/runtime,k8s.io/apimachinery/pkg/version \
# --output-package $(OUT_PACKAGE)/openapi \
# -O zz_generated.openapi
##################
# VERIFY CODEGEN #
@ -434,84 +491,77 @@ codegen-all: codegen-deepcopy-all codegen-crds-all codegen-client-all codegen-ap
.PHONY: verify-crds
verify-crds: codegen-crds-all ## Check CRDs are up to date
@git --no-pager diff config
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-crds-all".'
@echo 'To correct this, locally run "make codegen-crds-all", commit the changes, and re-run tests.'
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-crds-all".' >&2
@echo 'To correct this, locally run "make codegen-crds-all", commit the changes, and re-run tests.' >&2
@git diff --quiet --exit-code config
.PHONY: verify-client
verify-client: codegen-client-all ## Check client is up to date
@git --no-pager diff pkg/client
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-client-all".'
@echo 'To correct this, locally run "make codegen-client-all", commit the changes, and re-run tests.'
@git diff --quiet --exit-code pkg/client
@git --no-pager diff --ignore-space-change pkg/client
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-client-all".' >&2
@echo 'To correct this, locally run "make codegen-client-all", commit the changes, and re-run tests.' >&2
@git diff --ignore-space-change --quiet --exit-code pkg/client
.PHONY: verify-deepcopy
verify-deepcopy: codegen-deepcopy-all ## Check deepcopy functions are up to date
@git --no-pager diff api
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-deepcopy-all".'
@echo 'To correct this, locally run "make codegen-deepcopy-all", commit the changes, and re-run tests.'
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-deepcopy-all".' >&2
@echo 'To correct this, locally run "make codegen-deepcopy-all", commit the changes, and re-run tests.' >&2
@git diff --quiet --exit-code api
.PHONY: verify-api-docs
verify-api-docs: codegen-api-docs ## Check api reference docs are up to date
@git --no-pager diff docs
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-api-docs".'
@echo 'To correct this, locally run "make codegen-api-docs", commit the changes, and re-run tests.'
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-api-docs".' >&2
@echo 'To correct this, locally run "make codegen-api-docs", commit the changes, and re-run tests.' >&2
@git diff --quiet --exit-code docs
.PHONY: verify-helm
verify-helm: codegen-helm-all ## Check Helm charts are up to date
@git --no-pager diff charts
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-helm-all".'
@echo 'To correct this, locally run "make codegen-helm", commit the changes, and re-run tests.'
@echo 'If this test fails, it is because the git diff is non-empty after running "make codegen-helm-all".' >&2
@echo 'To correct this, locally run "make codegen-helm", commit the changes, and re-run tests.' >&2
@git diff --quiet --exit-code charts
.PHONY: verify-codegen
verify-codegen: verify-crds verify-client verify-deepcopy verify-api-docs verify-helm ## Verify all generated code and docs are up to date
##################################
# Create e2e Infrastructure
##################################
##############
# UNIT TESTS #
##############
.PHONY: kind-e2e-cluster
kind-e2e-cluster: $(KIND) ## Create kind cluster for e2e tests
$(KIND) create cluster --image=$(KIND_IMAGE)
# TODO(eddycharly): $(REPO) is wrong, it is always ghcr.io/kyverno in the source
.PHONY: e2e-kustomize
e2e-kustomize: $(KUSTOMIZE) ## Build kustomize manifests for e2e tests
cd config && \
$(KUSTOMIZE) edit set image $(REPO)/$(KYVERNOPRE_IMAGE)=$(LOCAL_KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV) && \
$(KUSTOMIZE) edit set image $(REPO)/$(KYVERNO_IMAGE)=$(LOCAL_KYVERNO_IMAGE):$(IMAGE_TAG_DEV)
$(KUSTOMIZE) build config/ -o config/install.yaml
.PHONY: e2e-init-container
e2e-init-container: kind-e2e-cluster | image-build-kyvernopre
$(KIND) load docker-image $(LOCAL_KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV)
.PHONY: e2e-kyverno-container
e2e-kyverno-container: kind-e2e-cluster | image-build-kyverno
$(KIND) load docker-image $(LOCAL_KYVERNO_IMAGE):$(IMAGE_TAG_DEV)
.PHONY: create-e2e-infrastructure
create-e2e-infrastructure: e2e-init-container e2e-kyverno-container e2e-kustomize | ## Setup infrastructure for e2e tests
##################################
# Testing & Code-Coverage
##################################
CODE_COVERAGE_FILE:= coverage
CODE_COVERAGE_FILE_TXT := $(CODE_COVERAGE_FILE).txt
CODE_COVERAGE_FILE := coverage
CODE_COVERAGE_FILE_TXT := $(CODE_COVERAGE_FILE).txt
CODE_COVERAGE_FILE_HTML := $(CODE_COVERAGE_FILE).html
.PHONY: test
test: test-clean test-unit test-e2e ## Clean tests cache then run unit and e2e tests
.PHONY: test-clean
test-clean: ## Clean tests cache
@echo " cleaning test cache"
go clean -testcache ./...
@echo Clean test cache... >&2
@go clean -testcache ./...
.PHONY: test-unit
test-unit: test-clean $(GO_ACC) ## Run unit tests
@echo Running unit tests... >&2
@$(GO_ACC) ./... -o $(CODE_COVERAGE_FILE_TXT)
.PHONY: code-cov-report
code-cov-report: test-clean ## Generate code coverage report
@echo Generating code coverage report... >&2
@GO111MODULE=on go test -v -coverprofile=coverage.out ./...
@go tool cover -func=coverage.out -o $(CODE_COVERAGE_FILE_TXT)
@go tool cover -html=coverage.out -o $(CODE_COVERAGE_FILE_HTML)
#############
# CLI TESTS #
#############
TEST_GIT_BRANCH ?= main
.PHONY: test-cli
test-cli: test-cli-policies test-cli-local test-cli-local-mutate test-cli-local-generate test-cli-test-case-selector-flag test-cli-registry
test-cli: test-cli-policies test-cli-local test-cli-local-mutate test-cli-local-generate test-cli-test-case-selector-flag test-cli-registry ## Run all CLI tests
.PHONY: test-cli-policies
test-cli-policies: $(CLI_BIN)
@ -537,15 +587,36 @@ test-cli-test-case-selector-flag: $(CLI_BIN)
test-cli-registry: $(CLI_BIN)
@$(CLI_BIN) test ./test/cli/registry --registry
test-unit: $(GO_ACC) ## Run unit tests
@echo " running unit tests"
$(GO_ACC) ./... -o $(CODE_COVERAGE_FILE_TXT)
##################################
# Create e2e Infrastructure
##################################
code-cov-report: ## Generate code coverage report
@echo " generating code coverage report"
GO111MODULE=on go test -v -coverprofile=coverage.out ./...
go tool cover -func=coverage.out -o $(CODE_COVERAGE_FILE_TXT)
go tool cover -html=coverage.out -o $(CODE_COVERAGE_FILE_HTML)
.PHONY: kind-e2e-cluster
kind-e2e-cluster: $(KIND) ## Create kind cluster for e2e tests
$(KIND) create cluster --image=$(KIND_IMAGE)
# TODO(eddycharly): $(REPO) is wrong, it is always ghcr.io/kyverno in the source
.PHONY: e2e-kustomize
e2e-kustomize: $(KUSTOMIZE) ## Build kustomize manifests for e2e tests
cd config && \
$(KUSTOMIZE) edit set image $(REPO_KYVERNOPRE)=$(LOCAL_KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV) && \
$(KUSTOMIZE) edit set image $(REPO_KYVERNO)=$(LOCAL_KYVERNO_IMAGE):$(IMAGE_TAG_DEV)
$(KUSTOMIZE) build config/ -o config/install.yaml
.PHONY: e2e-init-container
e2e-init-container: kind-e2e-cluster | image-build-kyvernopre
$(KIND) load docker-image $(LOCAL_KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV)
.PHONY: e2e-kyverno-container
e2e-kyverno-container: kind-e2e-cluster | image-build-kyverno
$(KIND) load docker-image $(LOCAL_KYVERNO_IMAGE):$(IMAGE_TAG_DEV)
.PHONY: create-e2e-infrastructure
create-e2e-infrastructure: e2e-init-container e2e-kyverno-container e2e-kustomize | ## Setup infrastructure for e2e tests
##################################
# Testing & Code-Coverage
##################################
# Test E2E
test-e2e:
@ -571,40 +642,52 @@ helm-test-values:
sed -i -e "s|repository: ghcr.io/kyverno/kyvernopre # init: replaced in e2e tests|repository: $(LOCAL_KYVERNOPRE_IMAGE)|" charts/kyverno/values.yaml
sed -i -e "s|repository: ghcr.io/kyverno/kyverno # kyverno: replaced in e2e tests|repository: $(LOCAL_KYVERNO_IMAGE)|" charts/kyverno/values.yaml
.PHONY: kustomize-crd
kustomize-crd: $(KUSTOMIZE) ## Create install.yaml
# Generate install.yaml that have all resources for kyverno
$(KUSTOMIZE) build ./config > ./config/install.yaml
# Generate install_debug.yaml that for developer testing
$(KUSTOMIZE) build ./config/debug > ./config/install_debug.yaml
# guidance https://github.com/kyverno/kyverno/wiki/Generate-a-Release
release:
$(KUSTOMIZE) build ./config > ./config/install.yaml
$(KUSTOMIZE) build ./config/release > ./config/release/install.yaml
release-notes:
@bash -c 'while IFS= read -r line ; do if [[ "$$line" == "## "* && "$$line" != "## $(VERSION)" ]]; then break ; fi; echo "$$line"; done < "CHANGELOG.md"' \
true
#########
# DEBUG #
#########
.PHONY: debug-deploy
debug-deploy: codegen-install ## Install debug manifests
@kubectl create -f ./config/install_debug.yaml || kubectl replace -f ./config/install_debug.yaml
##########
# GITHUB #
##########
.PHONY: gh-install-pin-github-action
gh-install-pin-github-action:
@npm install -g pin-github-action
.PHONY: gh-pin-actions
gh-pin-actions: gh-install-pin-github-action
@pin-github-action ./.github/workflows/release.yaml
########
# KIND #
########
.PHONY: kind-create-cluster
kind-create-cluster: $(KIND) ## Create kind cluster
@echo Create kind cluster... >&2
@$(KIND) create cluster --name $(KIND_NAME) --image $(KIND_IMAGE)
.PHONY: kind-delete-cluster
kind-delete-cluster: $(KIND) ## Delete kind cluster
@echo Delete kind cluster... >&2
@$(KIND) delete cluster --name $(KIND_NAME)
.PHONY: kind-load-kyvernopre
kind-load-kyvernopre: $(KIND) image-build-kyvernopre ## Build kyvernopre image and load it in kind cluster
@echo Load kyvernopre image... >&2
@$(KIND) load docker-image --name $(KIND_NAME) $(LOCAL_KYVERNOPRE_IMAGE):$(IMAGE_TAG_DEV)
.PHONY: kind-load-kyverno
kind-load-kyverno: $(KIND) image-build-kyverno ## Build kyverno image and load it in kind cluster
@echo Load kyverno image... >&2
@$(KIND) load docker-image --name $(KIND_NAME) $(LOCAL_KYVERNO_IMAGE):$(IMAGE_TAG_DEV)
.PHONY: kind-load-all
@ -612,19 +695,40 @@ kind-load-all: kind-load-kyvernopre kind-load-kyverno ## Build images and load t
.PHONY: kind-deploy-kyverno
kind-deploy-kyverno: kind-load-all ## Build images, load them in kind cluster and deploy kyverno helm chart
@echo Install kyverno chart... >&2
@helm upgrade --install kyverno --namespace kyverno --wait --create-namespace ./charts/kyverno \
--set image.repository=$(LOCAL_KYVERNO_IMAGE) \
--set image.tag=$(IMAGE_TAG_DEV) \
--set initImage.repository=$(LOCAL_KYVERNOPRE_IMAGE) \
--set initImage.tag=$(IMAGE_TAG_DEV) \
--set extraArgs={--autogenInternals=true}
--set initContainer.extraArgs={--loggingFormat=text} \
--set "extraArgs={--autogenInternals=true,--loggingFormat=text}"
@echo Restart kyverno pods... >&2
@kubectl rollout restart deployment -n kyverno kyverno
.PHONY: kind-deploy-kyverno-policies
kind-deploy-kyverno-policies: ## Deploy kyverno-policies helm chart
@echo Install kyverno-policies chart... >&2
@helm upgrade --install kyverno-policies --namespace kyverno --create-namespace ./charts/kyverno-policies
.PHONY: kind-deploy-metrics-server
kind-deploy-metrics-server: ## Deploy metrics-server helm chart
@echo Install metrics-server chart... >&2
@helm upgrade --install metrics-server --repo https://charts.bitnami.com/bitnami metrics-server -n kube-system \
--set extraArgs={--kubelet-insecure-tls=true} \
--set apiService.create=true
.PHONY: kind-deploy-all
kind-deploy-all: | kind-deploy-kyverno kind-deploy-kyverno-policies ## Build images, load them in kind cluster and deploy helm charts
kind-deploy-all: kind-deploy-metrics-server | kind-deploy-kyverno kind-deploy-kyverno-policies ## Build images, load them in kind cluster and deploy helm charts
.PHONY: kind-deploy-reporter
kind-deploy-reporter: ## Deploy policy-reporter helm chart
@echo Install policy-reporter chart... >&2
@helm upgrade --install policy-reporter --repo https://kyverno.github.io/policy-reporter policy-reporter -n policy-reporter \
--set ui.enabled=true \
--set kyvernoPlugin.enabled=true \
--create-namespace
@kubectl port-forward -n policy-reporter services/policy-reporter-ui 8082:8080
########
# HELP #

View file

@ -14,10 +14,10 @@ import (
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=clusterpolicies,scope="Cluster",shortName=cpol
// +kubebuilder:printcolumn:name="Background",type="string",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.ready`
// +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=boolean,JSONPath=`.status.ready`
// +kubebuilder:storageversion
// ClusterPolicy declares validation, mutation, and generation behaviors for matching resources.
@ -99,7 +99,7 @@ func (p *ClusterPolicy) IsReady() bool {
func (p *ClusterPolicy) Validate(clusterResources sets.String) (errs field.ErrorList) {
errs = append(errs, ValidateAutogenAnnotation(field.NewPath("metadata").Child("annotations"), p.GetAnnotations())...)
errs = append(errs, ValidatePolicyName(field.NewPath("name"), p.Name)...)
errs = append(errs, p.Spec.Validate(field.NewPath("spec"), p.IsNamespaced(), clusterResources)...)
errs = append(errs, p.Spec.Validate(field.NewPath("spec"), p.IsNamespaced(), p.Namespace, clusterResources)...)
return errs
}

View file

@ -6,6 +6,7 @@ import (
"github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/pod-security-admission/api"
)
@ -343,21 +344,15 @@ type PodSecurity struct {
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"`
// Images is a list of matching image patterns.
// 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"`
// 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" yaml:"restrictedField,omitempty"`
// Values defines the allowed values that can be excluded.
// +optional
Values []string `json:"values,omitempty" yaml:"values,omitempty"`
}
// DeserializeAnyPattern deserialize apiextensions.JSON to []interface{}
@ -504,6 +499,11 @@ type CloneList struct {
// Kinds is a list of resource kinds.
Kinds []string `json:"kinds,omitempty" yaml:"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"`
}
func (g *Generation) GetData() apiextensions.JSON {
@ -530,7 +530,7 @@ type Manifests struct {
// +kubebuilder:validation:Optional
Attestors []AttestorSet `json:"attestors,omitempty" yaml:"attestors,omitempty"`
// AnnotationDomain is custom domain of annotation for message nad signature. Default is "cosign.sigstore.dev".
// AnnotationDomain is custom domain of annotation for message and signature. Default is "cosign.sigstore.dev".
// +optional
AnnotationDomain string `json:"annotationDomain,omitempty" yaml:"annotationDomain,omitempty"`

View file

@ -3,4 +3,11 @@ 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"
)

View file

@ -1,3 +1,4 @@
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package
// +groupName=kyverno.io

View file

@ -12,10 +12,10 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Background",type="string",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.ready`
// +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=boolean,JSONPath=`.status.ready`
// +kubebuilder:resource:shortName=pol
// +kubebuilder:storageversion
@ -100,7 +100,7 @@ func (p *Policy) IsReady() bool {
func (p *Policy) Validate(clusterResources sets.String) (errs field.ErrorList) {
errs = append(errs, ValidateAutogenAnnotation(field.NewPath("metadata").Child("annotations"), p.GetAnnotations())...)
errs = append(errs, ValidatePolicyName(field.NewPath("name"), p.Name)...)
errs = append(errs, p.Spec.Validate(field.NewPath("spec"), p.IsNamespaced(), clusterResources)...)
errs = append(errs, p.Spec.Validate(field.NewPath("spec"), p.IsNamespaced(), p.Namespace, clusterResources)...)
return errs
}

View file

@ -2,6 +2,7 @@ package v1
import (
"encoding/json"
"fmt"
"testing"
"gotest.tools/assert"
@ -13,7 +14,7 @@ func Test_Validate_RuleType_EmptyRule(t *testing.T) {
Name: "validate-user-privilege",
}
path := field.NewPath("dummy")
errs := subject.Validate(path, false, nil)
errs := subject.Validate(path, false, "", nil)
assert.Equal(t, len(errs), 1)
assert.Equal(t, errs[0].Field, "dummy")
assert.Equal(t, errs[0].Type, field.ErrorTypeInvalid)
@ -90,7 +91,7 @@ func Test_Validate_RuleType_MultipleRule(t *testing.T) {
assert.NilError(t, err)
for _, rule := range policy.Spec.Rules {
path := field.NewPath("dummy")
errs := rule.Validate(path, false, nil)
errs := rule.Validate(path, false, "", nil)
assert.Assert(t, len(errs) != 0)
}
}
@ -145,7 +146,7 @@ func Test_Validate_RuleType_SingleRule(t *testing.T) {
assert.NilError(t, err)
for _, rule := range policy.Spec.Rules {
path := field.NewPath("dummy")
errs := rule.Validate(path, false, nil)
errs := rule.Validate(path, false, "", nil)
assert.Assert(t, len(errs) == 0)
}
}
@ -227,3 +228,609 @@ func Test_doesMatchExcludeConflict(t *testing.T) {
}
}
}
func Test_Validate_NamespacedPolicy_MutateRuleTargetNamespace(t *testing.T) {
path := field.NewPath("dummy")
testcases := []struct {
description string
rule []byte
errors func(r *Rule) field.ErrorList
}{
{
description: "Invalid mutate rule target namespace",
rule: []byte(`
{
"name": "auto-rollout-on-config-change",
"match": {
"resources": {
"kinds": [
"ConfigMap"
]
}
},
"mutate": {
"targets": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"namespace": "maddy"
},
{
"apiVersion": "v1",
"kind": "Service",
"namespace": "praddy"
}
],
"patchStrategicMerge": {
"metadata": {
"annotations": {
"kyverno/tls-changed:": "true"
}
}
}
}
}`),
errors: func(r *Rule) (errs field.ErrorList) {
return append(errs,
field.Invalid(path.Child("targets").Index(0).Child("namespace"), "maddy", "This field can be ignored or should have value of the namespace where the policy is being created"),
field.Invalid(path.Child("targets").Index(1).Child("namespace"), "praddy", "This field can be ignored or should have value of the namespace where the policy is being created"))
},
},
{
description: "Valid mutate rule target namespace",
rule: []byte(`
{
"name": "auto-rollout-on-config-change",
"match": {
"resources": {
"kinds": [
"ConfigMap"
]
}
},
"mutate": {
"targets": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"namespace": "amritapuri"
},
{
"apiVersion": "v1",
"kind": "Service",
"namespace": "amritapuri"
}
],
"patchStrategicMerge": {
"metadata": {
"annotations": {
"kyverno/tls-changed:": "true"
}
}
}
}
}`),
},
}
for _, testcase := range testcases {
var rule Rule
err := json.Unmarshal(testcase.rule, &rule)
assert.NilError(t, err)
errs := rule.ValidateMutationRuleTargetNamespace(path, true, "amritapuri")
var expectedErrs field.ErrorList
if testcase.errors != nil {
expectedErrs = testcase.errors(&rule)
}
assert.Equal(t, len(errs), len(expectedErrs))
for i := range errs {
assert.Equal(t, errs[i].Error(), expectedErrs[i].Error())
}
}
}
func Test_ValidatePSaControlNames(t *testing.T) {
path := field.NewPath("dummy")
testcases := []struct {
description string
rule []byte
errors func(r *Rule) field.ErrorList
}{
{
description: "baseline_with_restricted_control_name",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "Running as Non-root",
"images": [
"nginx",
"nodejs"
]
},
{
"controlName": "Seccomp",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
errors: func(r *Rule) (errs field.ErrorList) {
return append(errs,
field.Invalid(path.Child("podSecurity").Child("exclude").Index(0).Child("controlName"), "Running as Non-root", "Invalid control name defined at the given level"),
)
},
},
{
description: "baseline_with_baseline_control_name",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "/proc Mount Type",
"images": [
"nginx",
"nodejs"
]
},
{
"controlName": "Seccomp",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
},
{
description: "restricted_with_baseline_control_name",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "restricted",
"version": "v1.24",
"exclude": [
{
"controlName": "/proc Mount Type",
"images": [
"nginx",
"nodejs"
]
},
{
"controlName": "Seccomp",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
},
{
description: "restricted_with_restricted_control_name",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "restricted",
"version": "v1.24",
"exclude": [
{
"controlName": "Privilege Escalation",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
},
{
description: "container_level_control_with_images",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "restricted",
"version": "v1.24",
"exclude": [
{
"controlName": "Privilege Escalation"
}
]
}
}
}`),
errors: func(r *Rule) (errs field.ErrorList) {
return append(errs,
field.Invalid(path.Child("podSecurity").Child("exclude").Index(0).Child("controlName"), "Privilege Escalation", "exclude.images must be specified for the container level control"),
)
},
},
{
description: "container_level_control_without_images",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "restricted",
"version": "v1.24",
"exclude": [
{
"controlName": "Privilege Escalation",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
},
{
description: "pod_level_control_with_images",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "Host Namespaces",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
errors: func(r *Rule) (errs field.ErrorList) {
return append(errs,
field.Invalid(path.Child("podSecurity").Child("exclude").Index(0).Child("controlName"), "Host Namespaces", "exclude.images must not be specified for the pod level control"),
)
},
},
{
description: "pod_level_control_without_images",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "Host Namespaces"
}
]
}
}
}`),
},
{
description: "mixed_level_controls_without_images",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "SELinux"
}
]
}
}
}`),
},
{
description: "mixed_level_controls_with_images",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "SELinux",
"images": [
"nginx",
"nodejs"
]
}
]
}
}
}`),
},
{
description: "baseline_policy_with_restricted_control",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "baseline",
"version": "v1.24",
"exclude": [
{
"controlName": "Volume Types"
}
]
}
}
}`),
errors: func(r *Rule) (errs field.ErrorList) {
return append(errs,
field.Invalid(path.Child("podSecurity").Child("exclude").Index(0).Child("controlName"), "Volume Types", "Invalid control name defined at the given level"),
)
},
},
{
description: "baseline_policy_with_restricted_control",
rule: []byte(`
{
"name": "enforce-baseline-exclude-all-hostProcesses-all-containers-nginx",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"podSecurity": {
"level": "restricted",
"version": "latest",
"exclude": [
{
"controlName": "Privileged Containers",
"images": [
"dummyimagename*"
]
}
]
}
}
}`),
},
}
for _, testcase := range testcases {
var rule Rule
err := json.Unmarshal(testcase.rule, &rule)
assert.NilError(t, err)
errs := rule.ValidatePSaControlNames(path)
var expectedErrs field.ErrorList
if testcase.errors != nil {
expectedErrs = testcase.errors(&rule)
}
fmt.Println("errs", errs)
assert.Equal(t, len(errs), len(expectedErrs))
for i := range errs {
assert.Equal(t, errs[i].Error(), expectedErrs[i].Error())
}
}
}
func Test_Validate_ClusterPolicy_MutateRuleTargetNamespace(t *testing.T) {
path := field.NewPath("dummy")
testcases := []struct {
description string
rule []byte
errors func(r *Rule) field.ErrorList
}{
{
description: "Valid mutate rule target namespace",
rule: []byte(`
{
"name": "auto-rollout-on-config-change",
"match": {
"resources": {
"kinds": [
"ConfigMap"
]
}
},
"mutate": {
"targets": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"namespace": "maddy"
},
{
"apiVersion": "v1",
"kind": "Service",
"namespace": "praddy"
}
],
"patchStrategicMerge": {
"metadata": {
"annotations": {
"kyverno/tls-changed:": "true"
}
}
}
}
}`),
},
}
for _, testcase := range testcases {
var rule Rule
err := json.Unmarshal(testcase.rule, &rule)
assert.NilError(t, err)
errs := rule.ValidateMutationRuleTargetNamespace(path, false, "")
var expectedErrs field.ErrorList
if testcase.errors != nil {
expectedErrs = testcase.errors(&rule)
}
assert.Equal(t, len(errs), len(expectedErrs))
for i := range errs {
assert.Equal(t, errs[i].Error(), expectedErrs[i].Error())
}
}
}

View file

@ -5,6 +5,7 @@ import (
"fmt"
"reflect"
"github.com/kyverno/kyverno/pkg/pss/utils"
wildcard "github.com/kyverno/kyverno/pkg/utils/wildcard"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@ -139,6 +140,10 @@ func (r *Rule) IsMutateExisting() bool {
return r.Mutation.Targets != nil
}
func (r *Rule) IsPodSecurity() bool {
return r.Validation.PodSecurity != nil
}
// IsCloneSyncGenerate checks if the generate rule has the clone block with sync=true
func (r *Rule) GetCloneSyncForGenerate() (clone bool, sync bool) {
if !r.HasGenerate() {
@ -347,11 +352,57 @@ func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorL
return append(errs, field.Invalid(path, r, "Rule is matching an empty set"))
}
// ValidateMutationRuleTargetNamespace checks if the targets are scoped to the policy's namespace
func (r *Rule) ValidateMutationRuleTargetNamespace(path *field.Path, namespaced bool, policyNamespace string) (errs field.ErrorList) {
if r.HasMutate() && namespaced {
for idx, target := range r.Mutation.Targets {
if target.Namespace != "" && target.Namespace != policyNamespace {
errs = append(errs, field.Invalid(path.Child("targets").Index(idx).Child("namespace"), target.Namespace, "This field can be ignored or should have value of the namespace where the policy is being created"))
}
}
}
return errs
}
func (r *Rule) ValidatePSaControlNames(path *field.Path) (errs field.ErrorList) {
if r.IsPodSecurity() {
podSecurity := r.Validation.PodSecurity
forbiddenControls := []string{}
if podSecurity.Level == "baseline" {
forbiddenControls = utils.PSS_restricted_control_names
}
for idx, exclude := range podSecurity.Exclude {
// container level control must specify images
if containsString(utils.PSS_container_level_control, exclude.ControlName) {
if len(exclude.Images) == 0 {
errs = append(errs, field.Invalid(path.Child("podSecurity").Child("exclude").Index(idx).Child("controlName"), exclude.ControlName, "exclude.images must be specified for the container level control"))
}
} else if containsString(utils.PSS_pod_level_control, exclude.ControlName) {
if len(exclude.Images) != 0 {
errs = append(errs, field.Invalid(path.Child("podSecurity").Child("exclude").Index(idx).Child("controlName"), exclude.ControlName, "exclude.images must not be specified for the pod level control"))
}
}
if containsString([]string{"Seccomp", "Capabilities"}, exclude.ControlName) {
continue
}
if containsString(forbiddenControls, exclude.ControlName) {
errs = append(errs, field.Invalid(path.Child("podSecurity").Child("exclude").Index(idx).Child("controlName"), exclude.ControlName, "Invalid control name defined at the given level"))
}
}
}
return errs
}
// Validate implements programmatic validation
func (r *Rule) Validate(path *field.Path, namespaced bool, clusterResources sets.String) (errs field.ErrorList) {
func (r *Rule) Validate(path *field.Path, namespaced bool, policyNamespace string, clusterResources sets.String) (errs field.ErrorList) {
errs = append(errs, r.ValidateRuleType(path)...)
errs = append(errs, r.ValidateMatchExcludeConflict(path)...)
errs = append(errs, r.MatchResources.Validate(path.Child("match"), namespaced, clusterResources)...)
errs = append(errs, r.ExcludeResources.Validate(path.Child("exclude"), namespaced, clusterResources)...)
errs = append(errs, r.ValidateMutationRuleTargetNamespace(path, namespaced, policyNamespace)...)
errs = append(errs, r.ValidatePSaControlNames(path)...)
return errs
}

View file

@ -43,7 +43,7 @@ func Test_Validate_UniqueRuleName(t *testing.T) {
}},
}
path := field.NewPath("dummy")
errs := subject.Validate(path, false, nil)
errs := subject.Validate(path, false, "", nil)
assert.Equal(t, len(errs), 1)
assert.Equal(t, errs[0].Field, "dummy.rules[1].name")
assert.Equal(t, errs[0].Type, field.ErrorTypeInvalid)

View file

@ -49,6 +49,7 @@ type Spec struct {
// Allowed values are audit or enforce. The default value is "audit".
// +optional
// +kubebuilder:validation:Enum=audit;enforce
// +kubebuilder:default=audit
ValidationFailureAction ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
// ValidationFailureActionOverrides is a Cluster Policy attribute that specifies ValidationFailureAction
@ -60,6 +61,7 @@ type Spec struct {
// 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"`
// SchemaValidation skips policy validation checks.
@ -232,17 +234,17 @@ func (s *Spec) ValidateRuleNames(path *field.Path) (errs field.ErrorList) {
}
// ValidateRules implements programmatic validation of Rules
func (s *Spec) ValidateRules(path *field.Path, namespaced bool, clusterResources sets.String) (errs field.ErrorList) {
func (s *Spec) ValidateRules(path *field.Path, namespaced bool, policyNamespace string, clusterResources sets.String) (errs field.ErrorList) {
errs = append(errs, s.ValidateRuleNames(path)...)
for i, rule := range s.Rules {
errs = append(errs, rule.Validate(path.Index(i), namespaced, clusterResources)...)
errs = append(errs, rule.Validate(path.Index(i), namespaced, policyNamespace, clusterResources)...)
}
return errs
}
// Validate implements programmatic validation
func (s *Spec) Validate(path *field.Path, namespaced bool, clusterResources sets.String) (errs field.ErrorList) {
errs = append(errs, s.ValidateRules(path.Child("rules"), namespaced, clusterResources)...)
func (s *Spec) Validate(path *field.Path, namespaced bool, policyNamespace string, clusterResources sets.String) (errs field.ErrorList) {
errs = append(errs, s.ValidateRules(path.Child("rules"), namespaced, policyNamespace, clusterResources)...)
if namespaced && len(s.ValidationFailureActionOverrides) > 0 {
errs = append(errs, field.Forbidden(path.Child("validationFailureActionOverrides"), "Use of validationFailureActionOverrides is supported only with ClusterPolicy"))
}

View file

@ -1,16 +1,16 @@
package v1
import (
log "github.com/kyverno/kyverno/pkg/logging"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
log "sigs.k8s.io/controller-runtime/pkg/log"
)
func FromJSON(in *apiextv1.JSON) apiextensions.JSON {
var out apiextensions.JSON
if err := apiextv1.Convert_v1_JSON_To_apiextensions_JSON(in, &out, nil); err != nil {
log.Log.Error(err, "failed to convert JSON to interface")
log.Error(err, "failed to convert JSON to interface")
}
return out
}
@ -21,7 +21,7 @@ func ToJSON(in apiextensions.JSON) *apiextv1.JSON {
}
var out apiextv1.JSON
if err := apiextv1.Convert_apiextensions_JSON_To_v1_JSON(&in, &out, nil); err != nil {
log.Log.Error(err, "failed to convert interface to JSON")
log.Error(err, "failed to convert interface to JSON")
}
return &out
}
@ -45,3 +45,12 @@ func ValidatePolicyName(path *field.Path, name string) (errs field.ErrorList) {
}
return errs
}
func containsString(list []string, key string) bool {
for _, val := range list {
if val == key {
return true
}
}
return false
}

View file

@ -259,6 +259,11 @@ func (in *CloneList) DeepCopyInto(out *CloneList) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloneList.
@ -958,11 +963,6 @@ func (in *PodSecurityStandard) DeepCopyInto(out *PodSecurityStandard) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Values != nil {
in, out := &in.Values, &out.Values
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityStandard.

View file

@ -0,0 +1,124 @@
/*
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.
*/
package v1alpha2
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type AdmissionReportSpec struct {
// Owner is a reference to the report owner (e.g. a Deployment, Namespace, or Node)
Owner metav1.OwnerReference `json:"owner"`
// PolicyReportSummary provides a summary of results
// +optional
Summary policyreportv1alpha2.PolicyReportSummary `json:"summary,omitempty"`
// PolicyReportResult provides result details
// +optional
Results []policyreportv1alpha2.PolicyReportResult `json:"results,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:shortName=admr
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=".owner.kind",priority=1
// +kubebuilder:printcolumn:name="Subject",type=string,JSONPath=".owner.name",priority=1
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Hash",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.hash']",priority=1
// AdmissionReport is the Schema for the AdmissionReports API
type AdmissionReport struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec AdmissionReportSpec `json:"spec"`
}
func (r *AdmissionReport) GetResults() []policyreportv1alpha2.PolicyReportResult {
return r.Spec.Results
}
func (r *AdmissionReport) SetResults(results []policyreportv1alpha2.PolicyReportResult) {
r.Spec.Results = results
}
func (r *AdmissionReport) SetSummary(summary policyreportv1alpha2.PolicyReportSummary) {
r.Spec.Summary = summary
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:scope=Cluster,shortName=cadmr
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=".scope.kind",priority=1
// +kubebuilder:printcolumn:name="Subject",type=string,JSONPath=".scope.name",priority=1
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Hash",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.hash']",priority=1
// ClusterAdmissionReport is the Schema for the ClusterAdmissionReports API
type ClusterAdmissionReport struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec AdmissionReportSpec `json:"spec"`
}
func (r *ClusterAdmissionReport) GetResults() []policyreportv1alpha2.PolicyReportResult {
return r.Spec.Results
}
func (r *ClusterAdmissionReport) SetResults(results []policyreportv1alpha2.PolicyReportResult) {
r.Spec.Results = results
}
func (r *ClusterAdmissionReport) SetSummary(summary policyreportv1alpha2.PolicyReportSummary) {
r.Spec.Summary = summary
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// AdmissionReportList contains a list of AdmissionReport
type AdmissionReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []AdmissionReport `json:"items"`
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterAdmissionReportList contains a list of ClusterAdmissionReport
type ClusterAdmissionReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterAdmissionReport `json:"items"`
}

View file

@ -0,0 +1,121 @@
/*
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.
*/
package v1alpha2
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type BackgroundScanReportSpec struct {
// PolicyReportSummary provides a summary of results
// +optional
Summary policyreportv1alpha2.PolicyReportSummary `json:"summary,omitempty"`
// PolicyReportResult provides result details
// +optional
Results []policyreportv1alpha2.PolicyReportResult `json:"results,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:shortName=bgscanr
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=".metadata.ownerReferences[0].kind",priority=1
// +kubebuilder:printcolumn:name="Subject",type=string,JSONPath=".metadata.ownerReferences[0].name",priority=1
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Hash",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.hash']",priority=1
// BackgroundScanReport is the Schema for the BackgroundScanReports API
type BackgroundScanReport struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec BackgroundScanReportSpec `json:"spec"`
}
func (r *BackgroundScanReport) GetResults() []policyreportv1alpha2.PolicyReportResult {
return r.Spec.Results
}
func (r *BackgroundScanReport) SetResults(results []policyreportv1alpha2.PolicyReportResult) {
r.Spec.Results = results
}
func (r *BackgroundScanReport) SetSummary(summary policyreportv1alpha2.PolicyReportSummary) {
r.Spec.Summary = summary
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:scope=Cluster,shortName=cbgscanr
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=".metadata.ownerReferences[0].kind",priority=1
// +kubebuilder:printcolumn:name="Subject",type=string,JSONPath=".metadata.ownerReferences[0].name",priority=1
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Hash",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.hash']",priority=1
// ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports API
type ClusterBackgroundScanReport struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec BackgroundScanReportSpec `json:"spec"`
}
func (r *ClusterBackgroundScanReport) GetResults() []policyreportv1alpha2.PolicyReportResult {
return r.Spec.Results
}
func (r *ClusterBackgroundScanReport) SetResults(results []policyreportv1alpha2.PolicyReportResult) {
r.Spec.Results = results
}
func (r *ClusterBackgroundScanReport) SetSummary(summary policyreportv1alpha2.PolicyReportSummary) {
r.Spec.Summary = summary
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BackgroundScanReportList contains a list of BackgroundScanReport
type BackgroundScanReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []BackgroundScanReport `json:"items"`
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterBackgroundScanReportList contains a list of ClusterBackgroundScanReport
type ClusterBackgroundScanReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterBackgroundScanReport `json:"items"`
}

View file

@ -1,71 +0,0 @@
/*
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.
*/
package v1alpha2
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:path=clusterreportchangerequests,scope="Cluster",shortName=crcr
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=`.scope.kind`,priority=1
// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.scope.name`,priority=1
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=`.summary.pass`
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=`.summary.fail`
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=`.summary.warn`
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=`.summary.error`
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=`.summary.skip`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// ClusterReportChangeRequest is the Schema for the ClusterReportChangeRequests API
type ClusterReportChangeRequest struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// Scope is an optional reference to the report scope (e.g. a Deployment, Namespace, or Node)
// +optional
Scope *corev1.ObjectReference `json:"scope,omitempty"`
// ScopeSelector is an optional selector for multiple scopes (e.g. Pods).
// Either one of, or none of, but not both of, Scope or ScopeSelector should be specified.
// +optional
ScopeSelector *metav1.LabelSelector `json:"scopeSelector,omitempty"`
// PolicyReportSummary provides a summary of results
// +optional
Summary policyreportv1alpha2.PolicyReportSummary `json:"summary,omitempty"`
// PolicyReportResult provides result details
// +optional
Results []policyreportv1alpha2.PolicyReportResult `json:"results,omitempty"`
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterReportChangeRequestList contains a list of ClusterReportChangeRequest
type ClusterReportChangeRequestList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterReportChangeRequest `json:"items"`
}

View file

@ -0,0 +1,32 @@
/*
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.
*/
package v1alpha2
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +kubebuilder:object:generate=false
// ReportInterface abstracts the concrete report change request type
type ReportInterface interface {
metav1.Object
GetResults() []policyreportv1alpha2.PolicyReportResult
SetResults([]policyreportv1alpha2.PolicyReportResult)
SetSummary(policyreportv1alpha2.PolicyReportSummary)
}

View file

@ -50,10 +50,14 @@ var (
// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ReportChangeRequest{},
&ReportChangeRequestList{},
&ClusterReportChangeRequest{},
&ClusterReportChangeRequestList{},
&AdmissionReport{},
&AdmissionReportList{},
&BackgroundScanReport{},
&BackgroundScanReportList{},
&ClusterAdmissionReport{},
&ClusterAdmissionReportList{},
&ClusterBackgroundScanReport{},
&ClusterBackgroundScanReportList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View file

@ -1,73 +0,0 @@
/*
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.
*/
package v1alpha2
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=`.scope.kind`,priority=1
// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.scope.name`,priority=1
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=`.summary.pass`
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=`.summary.fail`
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=`.summary.warn`
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=`.summary.error`
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=`.summary.skip`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:resource:shortName=rcr
// ReportChangeRequest is the Schema for the ReportChangeRequests API
type ReportChangeRequest struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// Scope is an optional reference to the report scope (e.g. a Deployment, Namespace, or Node)
// +optional
Scope *corev1.ObjectReference `json:"scope,omitempty"`
// ScopeSelector is an optional selector for multiple scopes (e.g. Pods).
// Either one of, or none of, but not both of, Scope or ScopeSelector should be specified.
// +optional
ScopeSelector *metav1.LabelSelector `json:"scopeSelector,omitempty"`
// PolicyReportSummary provides a summary of results
// +optional
Summary policyreportv1alpha2.PolicyReportSummary `json:"summary,omitempty"`
// PolicyReportResult provides result details
// +optional
Results []policyreportv1alpha2.PolicyReportResult `json:"results,omitempty"`
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ReportChangeRequestList contains a list of ReportChangeRequest
type ReportChangeRequestList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ReportChangeRequest `json:"items"`
}

View file

@ -23,26 +23,71 @@ package v1alpha2
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterReportChangeRequest) DeepCopyInto(out *ClusterReportChangeRequest) {
func (in *AdmissionReport) DeepCopyInto(out *AdmissionReport) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
if in.Scope != nil {
in, out := &in.Scope, &out.Scope
*out = new(v1.ObjectReference)
**out = **in
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionReport.
func (in *AdmissionReport) DeepCopy() *AdmissionReport {
if in == nil {
return nil
}
if in.ScopeSelector != nil {
in, out := &in.ScopeSelector, &out.ScopeSelector
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
out := new(AdmissionReport)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *AdmissionReport) 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 *AdmissionReportList) DeepCopyInto(out *AdmissionReportList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]AdmissionReport, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionReportList.
func (in *AdmissionReportList) DeepCopy() *AdmissionReportList {
if in == nil {
return nil
}
out := new(AdmissionReportList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *AdmissionReportList) 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 *AdmissionReportSpec) DeepCopyInto(out *AdmissionReportSpec) {
*out = *in
in.Owner.DeepCopyInto(&out.Owner)
out.Summary = in.Summary
if in.Results != nil {
in, out := &in.Results, &out.Results
@ -53,18 +98,36 @@ func (in *ClusterReportChangeRequest) DeepCopyInto(out *ClusterReportChangeReque
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterReportChangeRequest.
func (in *ClusterReportChangeRequest) DeepCopy() *ClusterReportChangeRequest {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionReportSpec.
func (in *AdmissionReportSpec) DeepCopy() *AdmissionReportSpec {
if in == nil {
return nil
}
out := new(ClusterReportChangeRequest)
out := new(AdmissionReportSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BackgroundScanReport) DeepCopyInto(out *BackgroundScanReport) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackgroundScanReport.
func (in *BackgroundScanReport) DeepCopy() *BackgroundScanReport {
if in == nil {
return nil
}
out := new(BackgroundScanReport)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterReportChangeRequest) DeepCopyObject() runtime.Object {
func (in *BackgroundScanReport) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@ -72,31 +135,31 @@ func (in *ClusterReportChangeRequest) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterReportChangeRequestList) DeepCopyInto(out *ClusterReportChangeRequestList) {
func (in *BackgroundScanReportList) DeepCopyInto(out *BackgroundScanReportList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterReportChangeRequest, len(*in))
*out = make([]BackgroundScanReport, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterReportChangeRequestList.
func (in *ClusterReportChangeRequestList) DeepCopy() *ClusterReportChangeRequestList {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackgroundScanReportList.
func (in *BackgroundScanReportList) DeepCopy() *BackgroundScanReportList {
if in == nil {
return nil
}
out := new(ClusterReportChangeRequestList)
out := new(BackgroundScanReportList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterReportChangeRequestList) DeepCopyObject() runtime.Object {
func (in *BackgroundScanReportList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@ -104,20 +167,8 @@ func (in *ClusterReportChangeRequestList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ReportChangeRequest) DeepCopyInto(out *ReportChangeRequest) {
func (in *BackgroundScanReportSpec) DeepCopyInto(out *BackgroundScanReportSpec) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
if in.Scope != nil {
in, out := &in.Scope, &out.Scope
*out = new(v1.ObjectReference)
**out = **in
}
if in.ScopeSelector != nil {
in, out := &in.ScopeSelector, &out.ScopeSelector
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
out.Summary = in.Summary
if in.Results != nil {
in, out := &in.Results, &out.Results
@ -128,18 +179,36 @@ func (in *ReportChangeRequest) DeepCopyInto(out *ReportChangeRequest) {
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportChangeRequest.
func (in *ReportChangeRequest) DeepCopy() *ReportChangeRequest {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackgroundScanReportSpec.
func (in *BackgroundScanReportSpec) DeepCopy() *BackgroundScanReportSpec {
if in == nil {
return nil
}
out := new(ReportChangeRequest)
out := new(BackgroundScanReportSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterAdmissionReport) DeepCopyInto(out *ClusterAdmissionReport) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterAdmissionReport.
func (in *ClusterAdmissionReport) DeepCopy() *ClusterAdmissionReport {
if in == nil {
return nil
}
out := new(ClusterAdmissionReport)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ReportChangeRequest) DeepCopyObject() runtime.Object {
func (in *ClusterAdmissionReport) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@ -147,31 +216,89 @@ func (in *ReportChangeRequest) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ReportChangeRequestList) DeepCopyInto(out *ReportChangeRequestList) {
func (in *ClusterAdmissionReportList) DeepCopyInto(out *ClusterAdmissionReportList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ReportChangeRequest, len(*in))
*out = make([]ClusterAdmissionReport, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportChangeRequestList.
func (in *ReportChangeRequestList) DeepCopy() *ReportChangeRequestList {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterAdmissionReportList.
func (in *ClusterAdmissionReportList) DeepCopy() *ClusterAdmissionReportList {
if in == nil {
return nil
}
out := new(ReportChangeRequestList)
out := new(ClusterAdmissionReportList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ReportChangeRequestList) DeepCopyObject() runtime.Object {
func (in *ClusterAdmissionReportList) 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 *ClusterBackgroundScanReport) DeepCopyInto(out *ClusterBackgroundScanReport) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBackgroundScanReport.
func (in *ClusterBackgroundScanReport) DeepCopy() *ClusterBackgroundScanReport {
if in == nil {
return nil
}
out := new(ClusterBackgroundScanReport)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterBackgroundScanReport) 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 *ClusterBackgroundScanReportList) DeepCopyInto(out *ClusterBackgroundScanReportList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterBackgroundScanReport, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBackgroundScanReportList.
func (in *ClusterBackgroundScanReportList) DeepCopy() *ClusterBackgroundScanReportList {
if in == nil {
return nil
}
out := new(ClusterBackgroundScanReportList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterBackgroundScanReportList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}

View file

@ -15,10 +15,10 @@ import (
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=clusterpolicies,scope="Cluster",shortName=cpol
// +kubebuilder:printcolumn:name="Background",type="string",JSONPath=".spec.background"
// +kubebuilder:printcolumn:name="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.ready`
// +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=boolean,JSONPath=`.status.ready`
// ClusterPolicy declares validation, mutation, and generation behaviors for matching resources.
type ClusterPolicy struct {

View file

@ -13,10 +13,10 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Background",type="string",JSONPath=".spec.background"
// +kubebuilder:printcolumn:name="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.ready`
// +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=boolean,JSONPath=`.status.ready`
// +kubebuilder:resource:shortName=pol
// Policy declares validation, mutation, and generation behaviors for matching resources.
@ -27,6 +27,10 @@ type Policy struct {
// Spec defines policy behaviors and contains one or more rules.
Spec Spec `json:"spec" yaml:"spec"`
// Status contains policy runtime data.
// +optional
Status kyvernov1.PolicyStatus `json:"status,omitempty" yaml:"status,omitempty"`
}
// HasAutoGenAnnotation checks if a policy has auto-gen annotation
@ -84,6 +88,11 @@ func (p *Policy) IsNamespaced() bool {
return true
}
// IsReady indicates if the policy is ready to serve the admission request
func (p *Policy) IsReady() bool {
return p.Status.IsReady()
}
// Validate implements programmatic validation.
// namespaced means that the policy is bound to a namespace and therefore
// should not filter/generate cluster wide resources.

View file

@ -33,6 +33,7 @@ type Spec struct {
// Allowed values are audit or enforce. The default value is "audit".
// +optional
// +kubebuilder:validation:Enum=audit;enforce
// +kubebuilder:default=audit
ValidationFailureAction kyvernov1.ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
// ValidationFailureActionOverrides is a Cluster Policy attribute that specifies ValidationFailureAction
@ -44,6 +45,7 @@ type Spec struct {
// 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"`
// SchemaValidation skips policy validation checks.

View file

@ -230,6 +230,7 @@ func (in *Policy) DeepCopyInto(out *Policy) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Policy.

View file

@ -21,9 +21,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
@ -62,9 +59,22 @@ type ClusterPolicyReport struct {
Results []PolicyReportResult `json:"results,omitempty"`
}
// ClusterPolicyReportList contains a list of ClusterPolicyReport
func (r *ClusterPolicyReport) GetResults() []PolicyReportResult {
return r.Results
}
func (r *ClusterPolicyReport) SetResults(results []PolicyReportResult) {
r.Results = results
}
func (r *ClusterPolicyReport) SetSummary(summary PolicyReportSummary) {
r.Summary = summary
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterPolicyReportList contains a list of ClusterPolicyReport
type ClusterPolicyReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`

View file

@ -0,0 +1,136 @@
/*
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.
*/
package v1alpha2
import (
"encoding/json"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Status specifies state of a policy result
const (
StatusPass = "pass"
StatusFail = "fail"
StatusWarn = "warn"
StatusError = "error"
StatusSkip = "skip"
)
// Severity specifies priority of a policy result
const (
SeverityCritical = "critical"
SeverityHigh = "high"
SeverityMedium = "medium"
SeverityLow = "low"
SeverityInfo = "info"
)
// PolicyReportSummary provides a status count summary
type PolicyReportSummary struct {
// Pass provides the count of policies whose requirements were met
// +optional
Pass int `json:"pass"`
// Fail provides the count of policies whose requirements were not met
// +optional
Fail int `json:"fail"`
// Warn provides the count of non-scored policies whose requirements were not met
// +optional
Warn int `json:"warn"`
// Error provides the count of policies that could not be evaluated
// +optional
Error int `json:"error"`
// Skip indicates the count of policies that were not selected for evaluation
// +optional
Skip int `json:"skip"`
}
func (prs PolicyReportSummary) ToMap() map[string]interface{} {
b, _ := json.Marshal(&prs)
var m map[string]interface{}
_ = json.Unmarshal(b, &m)
return m
}
// PolicyResult has one of the following values:
// - pass: indicates that the policy requirements are met
// - fail: indicates that the policy requirements are not met
// - warn: indicates that the policy requirements and not met, and the policy is not scored
// - error: indicates that the policy could not be evaluated
// - skip: indicates that the policy was not selected based on user inputs or applicability
//
// +kubebuilder:validation:Enum=pass;fail;warn;error;skip
type PolicyResult string
// PolicySeverity has one of the following values:
// - critical
// - high
// - low
// - medium
// - info
// +kubebuilder:validation:Enum=critical;high;low;medium;info
type PolicySeverity string
// PolicyReportResult provides the result for an individual policy
type PolicyReportResult struct {
// Source is an identifier for the policy engine that manages this report
// +optional
Source string `json:"source"`
// Policy is the name or identifier of the policy
Policy string `json:"policy"`
// Rule is the name or identifier of the rule within the policy
// +optional
Rule string `json:"rule,omitempty"`
// Subjects is an optional reference to the checked Kubernetes resources
// +optional
Resources []corev1.ObjectReference `json:"resources,omitempty"`
// SubjectSelector is an optional label selector for checked Kubernetes resources.
// For example, a policy result may apply to all pods that match a label.
// Either a Subject or a SubjectSelector can be specified.
// If neither are provided, the result is assumed to be for the policy report scope.
// +optional
ResourceSelector *metav1.LabelSelector `json:"resourceSelector,omitempty"`
// Description is a short user friendly message for the policy rule
Message string `json:"message,omitempty"`
// Result indicates the outcome of the policy rule execution
Result PolicyResult `json:"result,omitempty"`
// Scored indicates if this result is scored
Scored bool `json:"scored,omitempty"`
// Properties provides additional information for the policy rule
Properties map[string]string `json:"properties,omitempty"`
// Timestamp indicates the time the result was found
Timestamp metav1.Timestamp `json:"timestamp,omitempty"`
// Category indicates policy category
// +optional
Category string `json:"category,omitempty"`
// Severity indicates policy check result criticality
// +optional
Severity PolicySeverity `json:"severity,omitempty"`
}

View file

@ -14,130 +14,10 @@ limitations under the License.
package v1alpha2
import (
"encoding/json"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// Status specifies state of a policy result
const (
StatusPass = "pass"
StatusFail = "fail"
StatusWarn = "warn"
StatusError = "error"
StatusSkip = "skip"
)
// Severity specifies priority of a policy result
const (
SeverityCritical = "critical"
SeverityHigh = "high"
SeverityMedium = "medium"
SeverityLow = "low"
SeverityInfo = "info"
)
// PolicyReportSummary provides a status count summary
type PolicyReportSummary struct {
// Pass provides the count of policies whose requirements were met
// +optional
Pass int `json:"pass"`
// Fail provides the count of policies whose requirements were not met
// +optional
Fail int `json:"fail"`
// Warn provides the count of non-scored policies whose requirements were not met
// +optional
Warn int `json:"warn"`
// Error provides the count of policies that could not be evaluated
// +optional
Error int `json:"error"`
// Skip indicates the count of policies that were not selected for evaluation
// +optional
Skip int `json:"skip"`
}
func (prs PolicyReportSummary) ToMap() map[string]interface{} {
b, _ := json.Marshal(&prs)
var m map[string]interface{}
_ = json.Unmarshal(b, &m)
return m
}
// PolicyResult has one of the following values:
// - pass: indicates that the policy requirements are met
// - fail: indicates that the policy requirements are not met
// - warn: indicates that the policy requirements and not met, and the policy is not scored
// - error: indicates that the policy could not be evaluated
// - skip: indicates that the policy was not selected based on user inputs or applicability
//
// +kubebuilder:validation:Enum=pass;fail;warn;error;skip
type PolicyResult string
// PolicySeverity has one of the following values:
// - critical
// - high
// - low
// - medium
// - info
// +kubebuilder:validation:Enum=critical;high;low;medium;info
type PolicySeverity string
// PolicyReportResult provides the result for an individual policy
type PolicyReportResult struct {
// Source is an identifier for the policy engine that manages this report
// +optional
Source string `json:"source"`
// Policy is the name or identifier of the policy
Policy string `json:"policy"`
// Rule is the name or identifier of the rule within the policy
// +optional
Rule string `json:"rule,omitempty"`
// Subjects is an optional reference to the checked Kubernetes resources
// +optional
Resources []corev1.ObjectReference `json:"resources,omitempty"`
// SubjectSelector is an optional label selector for checked Kubernetes resources.
// For example, a policy result may apply to all pods that match a label.
// Either a Subject or a SubjectSelector can be specified.
// If neither are provided, the result is assumed to be for the policy report scope.
// +optional
ResourceSelector *metav1.LabelSelector `json:"resourceSelector,omitempty"`
// Description is a short user friendly message for the policy rule
Message string `json:"message,omitempty"`
// Result indicates the outcome of the policy rule execution
Result PolicyResult `json:"result,omitempty"`
// Scored indicates if this result is scored
Scored bool `json:"scored,omitempty"`
// Properties provides additional information for the policy rule
Properties map[string]string `json:"properties,omitempty"`
// Timestamp indicates the time the result was found
Timestamp metav1.Timestamp `json:"timestamp,omitempty"`
// Category indicates policy category
// +optional
Category string `json:"category,omitempty"`
// Severity indicates policy check result criticality
// +optional
Severity PolicySeverity `json:"severity,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
@ -175,9 +55,22 @@ type PolicyReport struct {
Results []PolicyReportResult `json:"results,omitempty"`
}
// PolicyReportList contains a list of PolicyReport
func (r *PolicyReport) GetResults() []PolicyReportResult {
return r.Results
}
func (r *PolicyReport) SetResults(results []PolicyReportResult) {
r.Results = results
}
func (r *PolicyReport) SetSummary(summary PolicyReportSummary) {
r.Summary = summary
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PolicyReportList contains a list of PolicyReport
type PolicyReportList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`

View file

@ -27,12 +27,18 @@ annotations:
# valid kinds are: added, changed, deprecated, removed, fixed and security
artifacthub.io/changes: |
- kind: added
description: Added possibility to define additional init and sidecar container
description: Added possibility to define additional init and sidecar container.
- kind: added
description: Added ability to remove namespaces from default resourceFilters list
description: Added ability to remove namespaces from default resourceFilters list.
- kind: added
description: Prevent installing Kyverno in namespace kube-system.
- kind: fixed
description: Docs for generatecontrollerExtraResources.
- kind: changed
description: Enable autogen internals by default.
- kind: fixed
description: Self signed certificates not using SANs.
- kind: added
description: Extra args support for init container.
- kind: added
description: Allow overriding of test security context and resource block.

View file

@ -75,6 +75,7 @@ The command removes all the Kubernetes components associated with the chart and
| initImage.repository | string | `"ghcr.io/kyverno/kyvernopre"` | Image repository |
| initImage.tag | string | `nil` | Image tag If initImage.tag is missing, defaults to image.tag |
| initImage.pullPolicy | string | `nil` | Image pull policy If initImage.pullPolicy is missing, defaults to image.pullPolicy |
| initContainer.extraArgs | list | `["--loggingFormat=text"]` | Extra arguments to give to the kyvernopre binary. |
| testImage.repository | string | `nil` | Image repository Defaults to `busybox` if omitted |
| testImage.tag | string | `nil` | Image tag Defaults to `latest` if omitted |
| testImage.pullPolicy | string | `nil` | Image pull policy Defaults to image.pullPolicy if omitted |
@ -83,6 +84,7 @@ The command removes all the Kubernetes components associated with the chart and
| podAnnotations | object | `{}` | Additional annotations to add to each pod |
| podSecurityContext | object | `{}` | Security context for the pod |
| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Security context for the containers |
| testSecurityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65534,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}}` | Security context for the test containers |
| priorityClassName | string | `""` | Optional priority class to be used for kyverno pods |
| antiAffinity.enable | bool | `true` | Pod antiAffinities toggle. Enabled by default but can be disabled if you want to schedule pods to the same node. |
| podAntiAffinity | object | See [values.yaml](values.yaml) | Pod anti affinity constraints. |
@ -96,7 +98,7 @@ The command removes all the Kubernetes components associated with the chart and
| dnsPolicy | string | `"ClusterFirst"` | `dnsPolicy` determines the manner in which DNS resolution happens in the cluster. In case of `hostNetwork: true`, usually, the `dnsPolicy` is suitable to be `ClusterFirstWithHostNet`. For further reference: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy. |
| envVarsInit | object | `{}` | Env variables for initContainers. |
| envVars | object | `{}` | Env variables for containers. |
| extraArgs | list | `["--autogenInternals=true"]` | Extra arguments to give to the binary. |
| extraArgs | list | `["--autogenInternals=true","--loggingFormat=text"]` | Extra arguments to give to the binary. |
| extraInitContainers | list | `[]` | Array of extra init containers |
| extraContainers | list | `[]` | Array of extra containers to run alongside kyverno |
| imagePullSecrets | object | `{}` | Image pull secrets for image verify and imageData policies. This will define the `--imagePullSecrets` Kyverno argument. |
@ -104,6 +106,8 @@ The command removes all the Kubernetes components associated with the chart and
| resources.requests | object | `{"cpu":"100m","memory":"128Mi"}` | Pod resource requests |
| initResources.limits | object | `{"cpu":"100m","memory":"256Mi"}` | Pod resource limits |
| initResources.requests | object | `{"cpu":"10m","memory":"64Mi"}` | Pod resource requests |
| testResources.limits | object | `{"cpu":"100m","memory":"256Mi"}` | Pod resource limits |
| testResources.requests | object | `{"cpu":"10m","memory":"64Mi"}` | Pod resource requests |
| livenessProbe | object | See [values.yaml](values.yaml) | Liveness probe. The block is directly forwarded into the deployment, so you can use whatever livenessProbe configuration you want. ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ |
| readinessProbe | object | See [values.yaml](values.yaml) | Readiness Probe. The block is directly forwarded into the deployment, so you can use whatever readinessProbe configuration you want. ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ |
| generatecontrollerExtraResources | list | `[]` | Additional resources to be added to controller RBAC permissions. |
@ -163,8 +167,10 @@ This chart comes with default resource filters that apply exclusions on a couple
- `SelfSubjectAccessReview`
- `Binding`
- `ReplicaSet`
- `ReportChangeRequest`
- `ClusterReportChangeRequest`
- `AdmissionReport`
- `ClusterAdmissionReport`
- `BackgroundScanReport`
- `ClusterBackgroundScanReport`
- all resources created by this chart itself
Those default exclusions are there to prevent disruptions as much as possible.

View file

@ -79,8 +79,10 @@ This chart comes with default resource filters that apply exclusions on a couple
- `SelfSubjectAccessReview`
- `Binding`
- `ReplicaSet`
- `ReportChangeRequest`
- `ClusterReportChangeRequest`
- `AdmissionReport`
- `ClusterAdmissionReport`
- `BackgroundScanReport`
- `ClusterBackgroundScanReport`
- all resources created by this chart itself
Those default exclusions are there to prevent disruptions as much as possible.

View file

@ -113,6 +113,14 @@ maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
{{- end }}
{{- end }}
{{- define "kyverno.testSecurityContext" -}}
{{- if semverCompare "<1.19" .Capabilities.KubeVersion.Version }}
{{ toYaml (omit .Values.testSecurityContext "seccompProfile") }}
{{- else }}
{{ toYaml .Values.testSecurityContext }}
{{- end }}
{{- end }}
{{- define "kyverno.imagePullSecret" }}
{{- printf "{\"auths\":{\"%s\":{\"auth\":\"%s\"}}}" .registry (printf "%s:%s" .username .password | b64enc) | b64enc }}
{{- end }}

View file

@ -49,13 +49,15 @@ metadata:
labels: {{ include "kyverno.labels" . | nindent 4 }}
rbac.authorization.k8s.io/aggregate-to-admin: "true"
app: kyverno
name: {{ template "kyverno.fullname" . }}:admin-reportchangerequest
name: {{ template "kyverno.fullname" . }}:admin-reports
rules:
- apiGroups:
- kyverno.io
- kyverno.io
resources:
- reportchangerequests
- clusterreportchangerequests
- admissionreports
- clusteradmissionreports
- backgroundscanreports
- clusterbackgroundscanreports
verbs:
- create
- delete

View file

@ -47,10 +47,10 @@ rules:
- generaterequests/status
- updaterequests
- updaterequests/status
- reportchangerequests
- reportchangerequests/status
- clusterreportchangerequests
- clusterreportchangerequests/status
- admissionreports
- clusteradmissionreports
- backgroundscanreports
- clusterbackgroundscanreports
verbs:
- create
- delete

File diff suppressed because it is too large Load diff

View file

@ -71,6 +71,10 @@ spec:
- name: kyverno-pre
image: {{ .Values.initImage.repository }}:{{ default .Chart.AppVersion (default .Values.image.tag .Values.initImage.tag) }}
imagePullPolicy: {{ default .Values.image.pullPolicy .Values.initImage.pullPolicy }}
{{- if .Values.initContainer.extraArgs }}
args:
{{ tpl (toYaml .Values.initContainer.extraArgs) . }}
{{- end }}
{{- with .Values.initResources }}
resources: {{ tpl (toYaml .) $ | nindent 12 }}
{{- end }}
@ -84,6 +88,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: KYVERNO_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KYVERNO_DEPLOYMENT
value: {{ template "kyverno.fullname" . }}
{{- with .Values.envVarsInit }}

View file

@ -1,6 +1,7 @@
{{- if .Values.createSelfSignedCert }}
{{- $ca := genCA (printf "*.%s.svc" (include "kyverno.namespace" .)) 1024 -}}
{{- $cert := genSignedCert (printf "%s.%s.svc" (include "kyverno.serviceName" .) (include "kyverno.namespace" .)) nil nil 1024 $ca -}}
{{- $svcName := (printf "%s.%s.svc" (include "kyverno.serviceName" .) (include "kyverno.namespace" .)) -}}
{{- $cert := genSignedCert $svcName nil (list $svcName) 1024 $ca -}}
apiVersion: v1
kind: Secret
metadata:

View file

@ -12,6 +12,12 @@ spec:
- name: wget
image: {{ .Values.testImage.repository | default "busybox" }}{{- if .Values.testImage.tag }}:{{ .Values.testImage.tag }}{{- end }}
imagePullPolicy: {{ default .Values.image.pullPolicy .Values.testImage.pullPolicy }}
{{- with .Values.testResources }}
resources: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- if .Values.testSecurityContext }}
securityContext: {{ include "kyverno.testSecurityContext" . | nindent 8 }}
{{- end }}
command:
- /bin/sh
- -c
@ -20,6 +26,12 @@ spec:
- name: wget-metrics
image: {{ .Values.testImage.repository | default "busybox" }}{{- if .Values.testImage.tag }}:{{ .Values.testImage.tag }}{{- end }}
imagePullPolicy: {{ default .Values.image.pullPolicy .Values.testImage.pullPolicy }}
{{- with .Values.testResources }}
resources: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- if .Values.testSecurityContext }}
securityContext: {{ include "kyverno.testSecurityContext" . | nindent 8 }}
{{- end }}
command:
- /bin/sh
- -c

View file

@ -44,6 +44,12 @@ initImage:
# If initImage.pullPolicy is missing, defaults to image.pullPolicy
pullPolicy:
initContainer:
# -- Extra arguments to give to the kyvernopre binary.
extraArgs:
- --loggingFormat=text
testImage:
# -- Image repository
# Defaults to `busybox` if omitted
@ -81,6 +87,20 @@ securityContext:
seccompProfile:
type: RuntimeDefault
# -- Security context for the test containers
testSecurityContext:
runAsUser: 65534
runAsGroup: 65534
runAsNonRoot: true
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
# -- Optional priority class to be used for kyverno pods
priorityClassName: ''
@ -142,6 +162,7 @@ envVars: {}
# -- Extra arguments to give to the binary.
extraArgs:
- --autogenInternals=true
- --loggingFormat=text
# -- Array of extra init containers
extraInitContainers: []
@ -190,6 +211,16 @@ initResources:
cpu: 10m
memory: 64Mi
testResources:
# -- Pod resource limits
limits:
cpu: 100m
memory: 256Mi
# -- Pod resource requests
requests:
cpu: 10m
memory: 64Mi
# -- Liveness probe.
# The block is directly forwarded into the deployment, so you can use whatever livenessProbe configuration you want.
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
@ -250,8 +281,10 @@ config:
- '[SelfSubjectAccessReview,*,*]'
- '[Binding,*,*]'
- '[ReplicaSet,*,*]'
- '[ReportChangeRequest,*,*]'
- '[ClusterReportChangeRequest,*,*]'
- '[AdmissionReport,*,*]'
- '[ClusterAdmissionReport,*,*]'
- '[BackgroundScanReport,*,*]'
- '[ClusterBackgroundScanReport,*,*]'
# exclude resources from the chart
- '[ClusterRole,*,{{ template "kyverno.fullname" . }}:*]'
- '[ClusterRoleBinding,*,{{ template "kyverno.fullname" . }}:*]'

View file

@ -1,6 +1,7 @@
package apply
import (
"context"
"fmt"
"os"
"path/filepath"
@ -13,12 +14,12 @@ import (
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/openapi"
policy2 "github.com/kyverno/kyverno/pkg/policy"
"github.com/kyverno/kyverno/pkg/policyreport"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/kubernetes"
log "sigs.k8s.io/controller-runtime/pkg/log"
yaml1 "sigs.k8s.io/yaml"
@ -43,6 +44,22 @@ type SkippedInvalidPolicies struct {
invalid []string
}
type ApplyCommandConfig struct {
KubeConfig string
Context string
Namespace string
MutateLogPath string
VariablesString string
ValuesFile string
UserInfoPath string
Cluster bool
PolicyReport bool
Stdin bool
RegistryAccess bool
ResourcePaths []string
PolicyPaths []string
}
var applyHelp = `
To apply on a resource:
@ -110,9 +127,7 @@ More info: https://kyverno.io/docs/kyverno-cli/
func Command() *cobra.Command {
var cmd *cobra.Command
var resourcePaths []string
var cluster, policyReport, stdin, registryAccess bool
var mutateLogPath, variablesString, valuesFile, namespace, userInfoPath string
applyCommandConfig := &ApplyCommandConfig{}
cmd = &cobra.Command{
Use: "apply",
Short: "applies policies on resources",
@ -126,43 +141,43 @@ func Command() *cobra.Command {
}
}
}()
rc, resources, skipInvalidPolicies, pvInfos, err := applyCommandHelper(resourcePaths, userInfoPath, cluster, policyReport, mutateLogPath, variablesString, valuesFile, namespace, policyPaths, stdin, registryAccess)
applyCommandConfig.PolicyPaths = policyPaths
rc, resources, skipInvalidPolicies, pvInfos, err := applyCommandConfig.applyCommandHelper()
if err != nil {
return err
}
PrintReportOrViolation(policyReport, rc, resourcePaths, len(resources), skipInvalidPolicies, stdin, pvInfos)
PrintReportOrViolation(applyCommandConfig.PolicyReport, rc, applyCommandConfig.ResourcePaths, len(resources), skipInvalidPolicies, applyCommandConfig.Stdin, pvInfos)
return nil
},
}
cmd.Flags().StringArrayVarP(&resourcePaths, "resource", "r", []string{}, "Path to resource files")
cmd.Flags().BoolVarP(&cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context")
cmd.Flags().StringVarP(&mutateLogPath, "output", "o", "", "Prints the mutated resources in provided file/directory")
cmd.Flags().StringArrayVarP(&applyCommandConfig.ResourcePaths, "resource", "r", []string{}, "Path to resource files")
cmd.Flags().BoolVarP(&applyCommandConfig.Cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context")
cmd.Flags().StringVarP(&applyCommandConfig.MutateLogPath, "output", "o", "", "Prints the mutated resources in provided file/directory")
// currently `set` flag supports variable for single policy applied on single resource
cmd.Flags().StringVarP(&userInfoPath, "userinfo", "u", "", "Admission Info including Roles, Cluster Roles and Subjects")
cmd.Flags().StringVarP(&variablesString, "set", "s", "", "Variables that are required")
cmd.Flags().StringVarP(&valuesFile, "values-file", "f", "", "File containing values for policy variables")
cmd.Flags().BoolVarP(&policyReport, "policy-report", "p", false, "Generates policy report when passed (default policyviolation)")
cmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Optional Policy parameter passed with cluster flag")
cmd.Flags().BoolVarP(&stdin, "stdin", "i", false, "Optional mutate policy parameter to pipe directly through to kubectl")
cmd.Flags().BoolVarP(&registryAccess, "registry", "", false, "If set to true, access the image registry using local docker credentials to populate external data")
cmd.Flags().StringVarP(&applyCommandConfig.UserInfoPath, "userinfo", "u", "", "Admission Info including Roles, Cluster Roles and Subjects")
cmd.Flags().StringVarP(&applyCommandConfig.VariablesString, "set", "s", "", "Variables that are required")
cmd.Flags().StringVarP(&applyCommandConfig.ValuesFile, "values-file", "f", "", "File containing values for policy variables")
cmd.Flags().BoolVarP(&applyCommandConfig.PolicyReport, "policy-report", "p", false, "Generates policy report when passed (default policyviolation)")
cmd.Flags().StringVarP(&applyCommandConfig.Namespace, "namespace", "n", "", "Optional Policy parameter passed with cluster flag")
cmd.Flags().BoolVarP(&applyCommandConfig.Stdin, "stdin", "i", false, "Optional mutate policy parameter to pipe directly through to kubectl")
cmd.Flags().BoolVarP(&applyCommandConfig.RegistryAccess, "registry", "", false, "If set to true, access the image registry using local docker credentials to populate external data")
cmd.Flags().StringVarP(&applyCommandConfig.KubeConfig, "kubeconfig", "", "", "path to kubeconfig file with authorization and master location information")
cmd.Flags().StringVarP(&applyCommandConfig.Context, "context", "", "", "The name of the kubeconfig context to use")
return cmd
}
func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster bool, policyReport bool, mutateLogPath string,
variablesString string, valuesFile string, namespace string, policyPaths []string, stdin bool, registryAccess bool,
) (rc *common.ResultCounts, resources []*unstructured.Unstructured, skipInvalidPolicies SkippedInvalidPolicies, pvInfos []policyreport.Info, err error) {
func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, resources []*unstructured.Unstructured, skipInvalidPolicies SkippedInvalidPolicies, pvInfos []policyreport.Info, err error) {
store.SetMock(true)
store.SetRegistryAccess(registryAccess)
kubernetesConfig := genericclioptions.NewConfigFlags(true)
store.SetRegistryAccess(c.RegistryAccess)
fs := memfs.New()
if valuesFile != "" && variablesString != "" {
if c.ValuesFile != "" && c.VariablesString != "" {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("pass the values either using set flag or values_file flag", err)
}
variables, globalValMap, valuesMap, namespaceSelectorMap, err := common.GetVariable(variablesString, valuesFile, fs, false, "")
variables, globalValMap, valuesMap, namespaceSelectorMap, err := common.GetVariable(c.VariablesString, c.ValuesFile, fs, false, "")
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to decode yaml", err)
@ -176,8 +191,8 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
}
var dClient dclient.Interface
if cluster {
restConfig, err := kubernetesConfig.ToRESTConfig()
if c.Cluster {
restConfig, err := config.CreateClientConfigWithContext(c.KubeConfig, c.Context)
if err != nil {
return rc, resources, skipInvalidPolicies, pvInfos, err
}
@ -185,31 +200,31 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
if err != nil {
return rc, resources, skipInvalidPolicies, pvInfos, err
}
dClient, err = dclient.NewClient(restConfig, kubeClient, nil, 15*time.Minute, make(chan struct{}))
dClient, err = dclient.NewClient(context.Background(), restConfig, kubeClient, nil, 15*time.Minute)
if err != nil {
return rc, resources, skipInvalidPolicies, pvInfos, err
}
}
if len(policyPaths) == 0 {
if len(c.PolicyPaths) == 0 {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("require policy", err)
}
if (len(policyPaths) > 0 && policyPaths[0] == "-") && len(resourcePaths) > 0 && resourcePaths[0] == "-" {
if (len(c.PolicyPaths) > 0 && c.PolicyPaths[0] == "-") && len(c.ResourcePaths) > 0 && c.ResourcePaths[0] == "-" {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("a stdin pipe can be used for either policies or resources, not both", err)
}
policies, err := common.GetPoliciesFromPaths(fs, policyPaths, false, "")
policies, err := common.GetPoliciesFromPaths(fs, c.PolicyPaths, false, "")
if err != nil {
fmt.Printf("Error: failed to load policies\nCause: %s\n", err)
os.Exit(1)
}
if len(resourcePaths) == 0 && !cluster {
if len(c.ResourcePaths) == 0 && !c.Cluster {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("resource file(s) or cluster required", err)
}
mutateLogPathIsDir, err := checkMutateLogPath(mutateLogPath)
mutateLogPathIsDir, err := checkMutateLogPath(c.MutateLogPath)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to create file/folder", err)
@ -219,13 +234,13 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
// empty the previous contents of the file just in case if the file already existed before with some content(so as to perform overwrites)
// the truncation of files for the case when mutateLogPath is dir, is handled under pkg/kyverno/apply/common.go
if !mutateLogPathIsDir && mutateLogPath != "" {
mutateLogPath = filepath.Clean(mutateLogPath)
if !mutateLogPathIsDir && c.MutateLogPath != "" {
c.MutateLogPath = filepath.Clean(c.MutateLogPath)
// Necessary for us to include the file via variable as it is part of the CLI.
_, err := os.OpenFile(mutateLogPath, os.O_TRUNC|os.O_WRONLY, 0o600) // #nosec G304
_, err := os.OpenFile(c.MutateLogPath, os.O_TRUNC|os.O_WRONLY, 0o600) // #nosec G304
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to truncate the existing file at "+mutateLogPath, err)
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to truncate the existing file at "+c.MutateLogPath, err)
}
return rc, resources, skipInvalidPolicies, pvInfos, err
}
@ -243,21 +258,21 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to marsal mutated policy", err)
}
resources, err = common.GetResourceAccordingToResourcePath(fs, resourcePaths, cluster, mutatedPolicies, dClient, namespace, policyReport, false, "")
resources, err = common.GetResourceAccordingToResourcePath(fs, c.ResourcePaths, c.Cluster, mutatedPolicies, dClient, c.Namespace, c.PolicyReport, false, "")
if err != nil {
fmt.Printf("Error: failed to load resources\nCause: %s\n", err)
os.Exit(1)
}
if (len(resources) > 1 || len(mutatedPolicies) > 1) && variablesString != "" {
if (len(resources) > 1 || len(mutatedPolicies) > 1) && c.VariablesString != "" {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("currently `set` flag supports variable for single policy applied on single resource ", nil)
}
// get the user info as request info from a different file
var userInfo v1beta1.RequestInfo
var subjectInfo store.Subject
if userInfoPath != "" {
userInfo, subjectInfo, err = common.GetUserInfoFromPath(fs, userInfoPath, false, "")
if c.UserInfoPath != "" {
userInfo, subjectInfo, err = common.GetUserInfoFromPath(fs, c.UserInfoPath, false, "")
if err != nil {
fmt.Printf("Error: failed to load request info\nCause: %s\n", err)
os.Exit(1)
@ -265,7 +280,7 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
store.SetSubjects(subjectInfo)
}
if variablesString != "" {
if c.VariablesString != "" {
variables = common.SetInStoreContext(mutatedPolicies, variables)
}
@ -293,7 +308,7 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
}
if len(mutatedPolicies) > 0 && len(resources) > 0 {
if !stdin {
if !c.Stdin {
if mutatedPolicyRulesCount > policyRulesCount {
fmt.Printf("\nauto-generated pod policies\nApplying %s to %s...\n", msgPolicyRules, msgResources)
} else {
@ -324,7 +339,7 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
if len(variable) > 0 {
if len(variables) == 0 {
// check policy in variable file
if valuesFile == "" || valuesMap[policy.GetName()] == nil {
if c.ValuesFile == "" || valuesMap[policy.GetName()] == nil {
skipInvalidPolicies.skipped = append(skipInvalidPolicies.skipped, policy.GetName())
continue
}
@ -339,7 +354,7 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError(fmt.Sprintf("policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag", policy.GetName(), resource.GetName()), err)
}
_, info, err := common.ApplyPolicyOnResource(policy, resource, mutateLogPath, mutateLogPathIsDir, thisPolicyResourceValues, userInfo, policyReport, namespaceSelectorMap, stdin, rc, true, nil)
_, info, err := common.ApplyPolicyOnResource(policy, resource, c.MutateLogPath, mutateLogPathIsDir, thisPolicyResourceValues, userInfo, c.PolicyReport, namespaceSelectorMap, c.Stdin, rc, true, nil)
if err != nil {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.GetName(), resource.GetName()).Error(), err)
}

View file

@ -12,12 +12,16 @@ func Test_Apply(t *testing.T) {
PolicyPaths []string
ResourcePaths []string
expectedPolicyReports []preport.PolicyReport
config ApplyCommandConfig
}
testcases := []TestCase{
{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
@ -31,8 +35,11 @@ func Test_Apply(t *testing.T) {
},
},
{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
@ -46,8 +53,11 @@ func Test_Apply(t *testing.T) {
},
},
{
PolicyPaths: []string{"../../../../test/cli/apply/policies"},
ResourcePaths: []string{"../../../../test/cli/apply/resource"},
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/apply/policies"},
ResourcePaths: []string{"../../../../test/cli/apply/resource"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
@ -71,7 +81,7 @@ func Test_Apply(t *testing.T) {
}
for _, tc := range testcases {
_, _, _, info, _ := applyCommandHelper(tc.ResourcePaths, "", false, true, "", "", "", "", tc.PolicyPaths, false, false)
_, _, _, info, _ := tc.config.applyCommandHelper()
resps := buildPolicyReports(info)
for i, resp := range resps {
compareSummary(tc.expectedPolicyReports[i].Summary, resp.UnstructuredContent()["summary"].(map[string]interface{}))

View file

@ -6,6 +6,7 @@ import (
"strings"
"time"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/pkg/engine/response"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
@ -109,7 +110,7 @@ func buildPolicyResults(infos []policyreport.Info) map[string][]policyreportv1al
result.Rule = rule.Name
result.Message = rule.Message
result.Result = policyreportv1alpha2.PolicyResult(rule.Status)
result.Source = policyreport.SourceValue
result.Source = kyvernov1.ValueKyvernoApp
result.Timestamp = now
results[appname] = append(results[appname], result)
}

View file

@ -3,7 +3,7 @@ package jp
import (
"encoding/json"
"fmt"
"io/ioutil"
"io"
"os"
"path/filepath"
"sort"
@ -37,7 +37,7 @@ func Command() *cobra.Command {
// https://github.com/jmespath/jp/blob/54882e03bd277fc4475a677fab1d35eaa478b839/jp.go
var expression string
if exprFile != "" {
byteExpr, err := ioutil.ReadFile(filepath.Clean(exprFile))
byteExpr, err := os.ReadFile(filepath.Clean(exprFile))
if err != nil {
return fmt.Errorf("error opening expression file: %w", err)
}
@ -64,7 +64,7 @@ func Command() *cobra.Command {
}
var input interface{}
if filename != "" {
f, err := ioutil.ReadFile(filepath.Clean(filename))
f, err := os.ReadFile(filepath.Clean(filename))
if err != nil {
return fmt.Errorf("error opening input file: %w", err)
}
@ -72,7 +72,7 @@ func Command() *cobra.Command {
return fmt.Errorf("error parsing input json: %w", err)
}
} else {
f, err := ioutil.ReadAll(os.Stdin)
f, err := io.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("error opening input file: %w", err)
}

View file

@ -3,7 +3,7 @@ package test
import (
"encoding/json"
"fmt"
"io/ioutil"
"io"
"net/url"
"os"
"path"
@ -428,7 +428,7 @@ func testCommandExecute(dirPath []string, fileName string, gitBranch string, tes
if path.Base(file.Name()) == fileName {
testYamlCount++
policyresoucePath := strings.Trim(yamlFilePath, fileName)
bytes, err := ioutil.ReadAll(file)
bytes, err := io.ReadAll(file)
if err != nil {
errors = append(errors, sanitizederror.NewWithError("Error: failed to read file", err))
continue
@ -483,7 +483,7 @@ func testCommandExecute(dirPath []string, fileName string, gitBranch string, tes
func getLocalDirTestFiles(fs billy.Filesystem, path, fileName string, rc *resultCounts, testFiles *int, openAPIController *openapi.Controller, tf *testFilter, failOnly, removeColor bool) []error {
var errors []error
files, err := ioutil.ReadDir(path)
files, err := os.ReadDir(path)
if err != nil {
return []error{fmt.Errorf("failed to read %v: %v", path, err.Error())}
}
@ -495,7 +495,7 @@ func getLocalDirTestFiles(fs billy.Filesystem, path, fileName string, rc *result
if file.Name() == fileName {
*testFiles++
// We accept the risk of including files here as we read the test dir only.
yamlFile, err := ioutil.ReadFile(filepath.Join(path, file.Name())) // #nosec G304
yamlFile, err := os.ReadFile(filepath.Join(path, file.Name())) // #nosec G304
if err != nil {
errors = append(errors, sanitizederror.NewWithError("unable to read yaml", err))
continue
@ -722,7 +722,7 @@ func buildPolicyResults(engineResponses []*response.EngineResponse, testResults
result.Rule = rule.Name
result.Result = policyreportv1alpha2.PolicyResult(rule.Status)
result.Source = policyreport.SourceValue
result.Source = kyvernov1.ValueKyvernoApp
result.Timestamp = now
results[resultKey] = result
}
@ -1226,9 +1226,6 @@ func printTestResult(resps map[string]policyreportv1alpha2.PolicyReportResult, t
}
}
if countDeprecatedResource > 0 {
fmt.Printf("\n Note : The resource field is being deprecated in 1.8.0 release. Please provide the resources under the resources parameter as an array in the results field \n")
}
printer.BorderTop, printer.BorderBottom, printer.BorderLeft, printer.BorderRight = true, true, true, true
printer.CenterSeparator = "│"
printer.ColumnSeparator = "│"

View file

@ -5,7 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"io"
"net/http"
"os"
"path/filepath"
@ -105,7 +105,7 @@ func GetPolicies(paths []string) (policies []kyvernov1.PolicyInterface, errors [
// apply file from a directory is possible only if the path is not HTTP URL
if !isHTTPPath && fileDesc.IsDir() {
files, err := ioutil.ReadDir(path)
files, err := os.ReadDir(path)
if err != nil {
err := fmt.Errorf("failed to process %v: %v", path, err.Error())
errors = append(errors, err)
@ -147,7 +147,7 @@ func GetPolicies(paths []string) (policies []kyvernov1.PolicyInterface, errors [
continue
}
fileBytes, err = ioutil.ReadAll(resp.Body)
fileBytes, err = io.ReadAll(resp.Body)
if err != nil {
err := fmt.Errorf("failed to process %v: %v", path, err.Error())
errors = append(errors, err)
@ -156,7 +156,7 @@ func GetPolicies(paths []string) (policies []kyvernov1.PolicyInterface, errors [
} else {
path = filepath.Clean(path)
// We accept the risk of including a user provided file here.
fileBytes, err = ioutil.ReadFile(path) // #nosec G304
fileBytes, err = os.ReadFile(path) // #nosec G304
if err != nil {
err := fmt.Errorf("failed to process %v: %v", path, err.Error())
errors = append(errors, err)
@ -267,13 +267,13 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit
if err != nil {
fmt.Printf("Unable to open variable file: %s. error: %s", valuesFile, err)
}
yamlFile, err = ioutil.ReadAll(filep)
yamlFile, err = io.ReadAll(filep)
if err != nil {
fmt.Printf("Unable to read variable files: %s. error: %s \n", filep, err)
}
} else {
// We accept the risk of including a user provided file here.
yamlFile, err = ioutil.ReadFile(filepath.Join(policyResourcePath, valuesFile)) // #nosec G304
yamlFile, err = os.ReadFile(filepath.Join(policyResourcePath, valuesFile)) // #nosec G304
if err != nil {
fmt.Printf("\n Unable to open variable file: %s. error: %s \n", valuesFile, err)
}
@ -621,7 +621,7 @@ func GetPoliciesFromPaths(fs billy.Filesystem, dirPath []string, isGit bool, pol
fmt.Printf("Error: file not available with path %s: %v", filep.Name(), err.Error())
continue
}
bytes, err := ioutil.ReadAll(filep)
bytes, err := io.ReadAll(filep)
if err != nil {
fmt.Printf("Error: failed to read file %s: %v", filep.Name(), err.Error())
continue
@ -703,7 +703,7 @@ func GetResourceAccordingToResourcePath(fs billy.Filesystem, resourcePaths []str
return nil, err
}
if fileDesc.IsDir() {
files, err := ioutil.ReadDir(resourcePaths[0])
files, err := os.ReadDir(resourcePaths[0])
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to parse %v", resourcePaths[0]), err)
}
@ -753,7 +753,7 @@ func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateRes
case response.RuleStatusFail:
ann := policy.GetAnnotations()
if scored, ok := ann[policyreport.ScoredLabel]; ok && scored == "false" {
if scored, ok := ann[kyvernov1.AnnotationPolicyScored]; ok && scored == "false" {
rc.Warn++
vrule.Status = policyreportv1alpha2.StatusWarn
break
@ -1013,7 +1013,7 @@ func GetResourceFromPath(fs billy.Filesystem, path string, isGit bool, policyRes
if fileErr != nil {
fmt.Printf("Unable to open %s file: %s. \nerror: %s", resourceType, path, err)
}
resourceBytes, err = ioutil.ReadAll(filep)
resourceBytes, err = io.ReadAll(filep)
}
} else {
resourceBytes, err = getFileBytes(path)
@ -1117,7 +1117,7 @@ func GetUserInfoFromPath(fs billy.Filesystem, path string, isGit bool, policyRes
if err != nil {
fmt.Printf("Unable to open userInfo file: %s. \nerror: %s", path, err)
}
bytes, err := ioutil.ReadAll(filep)
bytes, err := io.ReadAll(filep)
if err != nil {
fmt.Printf("Error: failed to read file %s: %v", filep.Name(), err.Error())
}
@ -1139,7 +1139,8 @@ func GetUserInfoFromPath(fs billy.Filesystem, path string, isGit bool, policyRes
}
} else {
var errors []error
bytes, err := ioutil.ReadFile(filepath.Join(policyResourcePath, path))
pathname := filepath.Clean(filepath.Join(policyResourcePath, path))
bytes, err := os.ReadFile(pathname)
if err != nil {
errors = append(errors, sanitizederror.NewWithError("unable to read yaml", err))
}

View file

@ -4,8 +4,9 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"io"
"net/http"
"os"
"path/filepath"
"strings"
@ -139,7 +140,7 @@ func GetResourcesWithTest(fs billy.Filesystem, policies []kyvernov1.PolicyInterf
fmt.Printf("Unable to open resource file: %s. error: %s", resourcePath, err)
continue
}
resourceBytes, _ = ioutil.ReadAll(filep)
resourceBytes, _ = io.ReadAll(filep)
} else {
resourceBytes, err = getFileBytes(resourcePath)
}
@ -233,14 +234,14 @@ func getFileBytes(path string) ([]byte, error) {
return nil, err
}
file, err = ioutil.ReadAll(resp.Body)
file, err = io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
} else {
path = filepath.Clean(path)
// We accept the risk of including a user provided file here.
file, err = ioutil.ReadFile(path) // #nosec G304
file, err = os.ReadFile(path) // #nosec G304
if err != nil {
return nil, err
}

View file

@ -7,8 +7,11 @@ import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
@ -16,8 +19,7 @@ import (
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/leaderelection"
"github.com/kyverno/kyverno/pkg/policyreport"
"github.com/kyverno/kyverno/pkg/signal"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/tls"
"github.com/kyverno/kyverno/pkg/utils"
"go.uber.org/multierr"
@ -25,57 +27,54 @@ import (
coordinationv1 "k8s.io/api/coordination/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"k8s.io/klog/v2/klogr"
"sigs.k8s.io/controller-runtime/pkg/log"
)
var (
kubeconfig string
setupLog = log.Log.WithName("setup")
setupLog = logging.WithName("setup")
clientRateLimitQPS float64
clientRateLimitBurst int
updateLabelSelector = &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: policyreport.LabelSelectorKey,
Operator: metav1.LabelSelectorOpDoesNotExist,
Values: []string{},
},
},
}
logFormat string
)
const (
policyReportKind string = "PolicyReport"
clusterPolicyReportKind string = "ClusterPolicyReport"
reportChangeRequestKind string = "ReportChangeRequest"
clusterReportChangeRequestKind string = "ClusterReportChangeRequest"
convertGenerateRequest string = "ConvertGenerateRequest"
policyReportKind string = "PolicyReport"
clusterPolicyReportKind string = "ClusterPolicyReport"
convertGenerateRequest string = "ConvertGenerateRequest"
)
func main() {
// clear flags initialized in static dependencies
if flag.CommandLine.Lookup("log_dir") != nil {
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
}
klog.InitFlags(nil) // add the block above before invoking klog.InitFlags()
log.SetLogger(klogr.New())
func parseFlags() error {
logging.Init(nil)
flag.StringVar(&logFormat, "loggingFormat", logging.TextFormat, "This determines the output format of the logger.")
flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
flag.Float64Var(&clientRateLimitQPS, "clientRateLimitQPS", 0, "Configure the maximum QPS to the Kubernetes API server from Kyverno. Uses the client default if zero.")
flag.IntVar(&clientRateLimitBurst, "clientRateLimitBurst", 0, "Configure the maximum burst for throttle. Uses the client default if zero.")
if err := flag.Set("v", "2"); err != nil {
klog.Fatalf("failed to set log level: %v", err)
return err
}
flag.Parse()
return nil
}
func main() {
// parse flags
if err := parseFlags(); err != nil {
fmt.Println("failed to parse flags", err)
os.Exit(1)
}
// setup logger
if err := logging.Setup(logFormat); err != nil {
fmt.Println("could not setup logger", err)
os.Exit(1)
}
// os signal handler
stopCh := signal.SetupSignalHandler()
signalCtx, signalCancel := signal.NotifyContext(logging.Background(), os.Interrupt, syscall.SIGTERM)
defer signalCancel()
stopCh := signalCtx.Done()
// create client config
clientConfig, err := config.CreateClientConfig(kubeconfig, clientRateLimitQPS, clientRateLimitBurst)
if err != nil {
@ -91,7 +90,7 @@ func main() {
// DYNAMIC CLIENT
// - client for all registered resources
client, err := dclient.NewClient(clientConfig, kubeClient, nil, 15*time.Minute, stopCh)
client, err := dclient.NewClient(signalCtx, clientConfig, kubeClient, nil, 15*time.Minute)
if err != nil {
setupLog.Error(err, "Failed to create client")
os.Exit(1)
@ -104,39 +103,30 @@ func main() {
}
// Exit for unsupported version of kubernetes cluster
if !utils.HigherThanKubernetesVersion(kubeClient.Discovery(), log.Log, 1, 16, 0) {
if !utils.HigherThanKubernetesVersion(kubeClient.Discovery(), logging.GlobalLogger(), 1, 16, 0) {
os.Exit(1)
}
requests := []request{
{policyReportKind},
{clusterPolicyReportKind},
{reportChangeRequestKind},
{clusterReportChangeRequestKind},
{convertGenerateRequest},
}
ctx, cancel := context.WithCancel(context.Background())
go func() {
defer signalCancel()
<-stopCh
cancel()
}()
addPolicyReportSelectorLabel(client)
addClusterPolicyReportSelectorLabel(client)
done := make(chan struct{})
defer close(done)
failure := false
run := func() {
run := func(context.Context) {
name := tls.GenerateRootCASecretName()
_, err = kubeClient.CoreV1().Secrets(config.KyvernoNamespace()).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
log.Log.V(2).Info("failed to fetch root CA secret", "name", name, "error", err.Error())
logging.V(2).Info("failed to fetch root CA secret", "name", name, "error", err.Error())
if !errors.IsNotFound(err) {
os.Exit(1)
}
@ -145,18 +135,18 @@ func main() {
name = tls.GenerateTLSPairSecretName()
_, err = kubeClient.CoreV1().Secrets(config.KyvernoNamespace()).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
log.Log.V(2).Info("failed to fetch TLS Pair secret", "name", name, "error", err.Error())
logging.V(2).Info("failed to fetch TLS Pair secret", "name", name, "error", err.Error())
if !errors.IsNotFound(err) {
os.Exit(1)
}
}
if err = acquireLeader(ctx, kubeClient); err != nil {
log.Log.V(2).Info("Failed to create lease 'kyvernopre-lock'")
if err = acquireLeader(signalCtx, kubeClient); err != nil {
logging.V(2).Info("Failed to create lease 'kyvernopre-lock'")
os.Exit(1)
}
// use pipline to pass request to cleanup resources
// use pipeline to pass request to cleanup resources
in := gen(done, stopCh, requests...)
// process requests
// processing routine count : 2
@ -166,33 +156,41 @@ func main() {
for err := range merge(done, stopCh, p1, p2) {
if err != nil {
failure = true
log.Log.Error(err, "failed to cleanup resource")
logging.Error(err, "failed to cleanup resource")
}
}
// if there is any failure then we fail process
if failure {
log.Log.V(2).Info("failed to cleanup prior configurations")
logging.V(2).Info("failed to cleanup prior configurations")
os.Exit(1)
}
os.Exit(0)
}
le, err := leaderelection.New("kyvernopre", config.KyvernoNamespace(), kubeClient, run, nil, log.Log.WithName("kyvernopre/LeaderElection"))
le, err := leaderelection.New(
logging.WithName("kyvernopre/LeaderElection"),
"kyvernopre",
config.KyvernoNamespace(),
kubeClient,
config.KyvernoPodName(),
run,
nil,
)
if err != nil {
setupLog.Error(err, "failed to elect a leader")
os.Exit(1)
}
le.Run(ctx)
le.Run(signalCtx)
}
func acquireLeader(ctx context.Context, kubeClient kubernetes.Interface) error {
_, err := kubeClient.CoordinationV1().Leases(config.KyvernoNamespace()).Get(ctx, "kyvernopre-lock", metav1.GetOptions{})
if err != nil {
log.Log.V(2).Info("Lease 'kyvernopre-lock' not found. Starting clean-up...")
logging.V(2).Info("Lease 'kyvernopre-lock' not found. Starting clean-up...")
} else {
log.Log.V(2).Info("Leader was elected, quitting")
logging.V(2).Info("Leader was elected, quitting")
os.Exit(0)
}
@ -208,14 +206,6 @@ func acquireLeader(ctx context.Context, kubeClient kubernetes.Interface) error {
func executeRequest(client dclient.Interface, kyvernoclient kyvernoclient.Interface, req request) error {
switch req.kind {
case policyReportKind:
return removePolicyReport(client, req.kind)
case clusterPolicyReportKind:
return removeClusterPolicyReport(client, req.kind)
case reportChangeRequestKind:
return removeReportChangeRequest(client, req.kind)
case clusterReportChangeRequestKind:
return removeClusterReportChangeRequest(client, req.kind)
case convertGenerateRequest:
return convertGR(kyvernoclient)
}
@ -257,7 +247,7 @@ func gen(done <-chan struct{}, stopCh <-chan struct{}, requests ...request) <-ch
// processes the requests
func process(client dclient.Interface, kyvernoclient kyvernoclient.Interface, done <-chan struct{}, stopCh <-chan struct{}, requests <-chan request) <-chan error {
logger := log.Log.WithName("process")
logger := logging.WithName("process")
out := make(chan error)
go func() {
defer close(out)
@ -278,7 +268,7 @@ func process(client dclient.Interface, kyvernoclient kyvernoclient.Interface, do
// waits for all processes to be complete and merges result
func merge(done <-chan struct{}, stopCh <-chan struct{}, processes ...<-chan error) <-chan error {
logger := log.Log.WithName("merge")
logger := logging.WithName("merge")
var wg sync.WaitGroup
out := make(chan error)
// gets the output from each process
@ -310,139 +300,8 @@ func merge(done <-chan struct{}, stopCh <-chan struct{}, processes ...<-chan err
return out
}
func removeClusterPolicyReport(client dclient.Interface, kind string) error {
logger := log.Log.WithName("removeClusterPolicyReport")
cpolrs, err := client.ListResource("", kind, "", policyreport.LabelSelector)
if err != nil {
logger.Error(err, "failed to list clusterPolicyReport")
return nil
}
for _, cpolr := range cpolrs.Items {
deleteResource(client, cpolr.GetAPIVersion(), cpolr.GetKind(), "", cpolr.GetName())
}
return nil
}
func removePolicyReport(client dclient.Interface, kind string) error {
logger := log.Log.WithName("removePolicyReport")
polrs, err := client.ListResource("", kind, metav1.NamespaceAll, policyreport.LabelSelector)
if err != nil {
logger.Error(err, "failed to list policyReport")
return nil
}
for _, polr := range polrs.Items {
deleteResource(client, polr.GetAPIVersion(), polr.GetKind(), polr.GetNamespace(), polr.GetName())
}
return nil
}
// Deprecated: New ClusterPolicyReports already has required labels, will be removed in
// 1.8.0 version
func addClusterPolicyReportSelectorLabel(client dclient.Interface) {
logger := log.Log.WithName("addClusterPolicyReportSelectorLabel")
cpolrs, err := client.ListResource("", clusterPolicyReportKind, "", updateLabelSelector)
if err != nil {
logger.Error(err, "failed to list clusterPolicyReport")
return
}
for _, cpolr := range cpolrs.Items {
if cpolr.GetName() == policyreport.GeneratePolicyReportName("", "") {
addSelectorLabel(client, cpolr.GetAPIVersion(), cpolr.GetKind(), "", cpolr.GetName())
}
}
}
// Deprecated: New PolicyReports already has required labels, will be removed in
// 1.8.0 version
func addPolicyReportSelectorLabel(client dclient.Interface) {
logger := log.Log.WithName("addPolicyReportSelectorLabel")
polrs, err := client.ListResource("", policyReportKind, metav1.NamespaceAll, updateLabelSelector)
if err != nil {
logger.Error(err, "failed to list policyReport")
return
}
for _, polr := range polrs.Items {
if polr.GetName() == policyreport.GeneratePolicyReportName(polr.GetNamespace(), "") {
addSelectorLabel(client, polr.GetAPIVersion(), polr.GetKind(), polr.GetNamespace(), polr.GetName())
}
}
}
func removeReportChangeRequest(client dclient.Interface, kind string) error {
logger := log.Log.WithName("removeReportChangeRequest")
ns := config.KyvernoNamespace()
rcrList, err := client.ListResource("", kind, ns, nil)
if err != nil {
logger.Error(err, "failed to list reportChangeRequest")
return nil
}
for _, rcr := range rcrList.Items {
deleteResource(client, rcr.GetAPIVersion(), rcr.GetKind(), rcr.GetNamespace(), rcr.GetName())
}
return nil
}
func removeClusterReportChangeRequest(client dclient.Interface, kind string) error {
crcrList, err := client.ListResource("", kind, "", nil)
if err != nil {
log.Log.Error(err, "failed to list clusterReportChangeRequest")
return nil
}
for _, crcr := range crcrList.Items {
deleteResource(client, crcr.GetAPIVersion(), crcr.GetKind(), "", crcr.GetName())
}
return nil
}
func deleteResource(client dclient.Interface, apiversion, kind, ns, name string) {
err := client.DeleteResource(apiversion, kind, ns, name, false)
if err != nil && !errors.IsNotFound(err) {
log.Log.Error(err, "failed to delete resource", "kind", kind, "name", name)
return
}
log.Log.V(2).Info("successfully cleaned up resource", "kind", kind, "name", name)
}
func addSelectorLabel(client dclient.Interface, apiversion, kind, ns, name string) {
res, err := client.GetResource(apiversion, kind, ns, name)
if err != nil && !errors.IsNotFound(err) {
log.Log.Error(err, "failed to get resource", "kind", kind, "name", name)
return
}
l, err := metav1.LabelSelectorAsMap(policyreport.LabelSelector)
if err != nil {
log.Log.Error(err, "failed to convert labels", "labels", policyreport.LabelSelector)
return
}
res.SetLabels(labels.Merge(res.GetLabels(), l))
_, err = client.UpdateResource(apiversion, kind, ns, res, false)
if err != nil {
log.Log.Error(err, "failed to update resource", "kind", kind, "name", name)
return
}
log.Log.V(2).Info("successfully updated resource labels", "kind", kind, "name", name)
}
func convertGR(pclient kyvernoclient.Interface) error {
logger := log.Log.WithName("convertGenerateRequest")
logger := logging.WithName("convertGenerateRequest")
var errors []error
grs, err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).List(context.TODO(), metav1.ListOptions{})

27
cmd/kyverno/controller.go Normal file
View file

@ -0,0 +1,27 @@
package main
import (
"context"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/controllers"
)
type controller struct {
name string
controller controllers.Controller
workers int
}
func newController(name string, c controllers.Controller, w int) controller {
return controller{
name: name,
controller: c,
workers: w,
}
}
func (c controller) run(ctx context.Context, logger logr.Logger) {
logger.Info("start controller...", "name", c.name)
c.controller.Run(ctx, c.workers)
}

View file

@ -1,28 +1,45 @@
package main
import (
"context"
"reflect"
)
// TODO: eventually move this in an util package
type informer interface {
type startable interface {
Start(stopCh <-chan struct{})
}
type informer interface {
startable
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
}
func startInformers(stopCh <-chan struct{}, informers ...informer) {
func startInformers[T startable](ctx context.Context, informers ...T) {
for i := range informers {
informers[i].Start(stopCh)
informers[i].Start(ctx.Done())
}
}
func waitForCacheSync(stopCh <-chan struct{}, informers ...informer) {
func waitForCacheSync(ctx context.Context, informers ...informer) bool {
ret := true
for i := range informers {
informers[i].WaitForCacheSync(stopCh)
for _, result := range informers[i].WaitForCacheSync(ctx.Done()) {
ret = ret && result
}
}
return ret
}
func startInformersAndWaitForCacheSync(stopCh <-chan struct{}, informers ...informer) {
startInformers(stopCh, informers...)
waitForCacheSync(stopCh, informers...)
func checkCacheSync[T comparable](status map[T]bool) bool {
ret := true
for _, s := range status {
ret = ret && s
}
return ret
}
func startInformersAndWaitForCacheSync(ctx context.Context, informers ...informer) bool {
startInformers(ctx, informers...)
return waitForCacheSync(ctx, informers...)
}

File diff suppressed because it is too large Load diff

View file

@ -2,11 +2,13 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./kyverno.io_admissionreports.yaml
- ./kyverno.io_backgroundscanreports.yaml
- ./kyverno.io_clusteradmissionreports.yaml
- ./kyverno.io_clusterbackgroundscanreports.yaml
- ./kyverno.io_clusterpolicies.yaml
- ./kyverno.io_clusterreportchangerequests.yaml
- ./kyverno.io_generaterequests.yaml
- ./kyverno.io_policies.yaml
- ./kyverno.io_reportchangerequests.yaml
- ./kyverno.io_updaterequests.yaml
- ./wgpolicyk8s.io_clusterpolicyreports.yaml
- ./wgpolicyk8s.io_policyreports.yaml

View file

@ -0,0 +1,331 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.1-0.20220629131006-1878064c4cdf
creationTimestamp: null
name: admissionreports.kyverno.io
spec:
group: kyverno.io
names:
kind: AdmissionReport
listKind: AdmissionReportList
plural: admissionreports
shortNames:
- admr
singular: admissionreport
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .owner.kind
name: Kind
priority: 1
type: string
- jsonPath: .owner.name
name: Subject
priority: 1
type: string
- jsonPath: .spec.summary.pass
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: Skip
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1alpha2
schema:
openAPIV3Schema:
description: AdmissionReport is the Schema for the AdmissionReports API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
owner:
description: Owner is a reference to the report owner (e.g. a Deployment,
Namespace, or Node)
properties:
apiVersion:
description: API version of the referent.
type: string
blockOwnerDeletion:
description: If true, AND if the owner has the "foregroundDeletion"
finalizer, then the owner cannot be deleted from the key-value
store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion
for how the garbage collector interacts with this field and
enforces the foreground deletion. Defaults to false. To set
this field, a user needs "delete" permission of the owner, otherwise
422 (Unprocessable Entity) will be returned.
type: boolean
controller:
description: If true, this reference points to the managing controller.
type: boolean
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names'
type: string
uid:
description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids'
type: string
required:
- apiVersion
- kind
- name
- uid
type: object
x-kubernetes-map-type: atomic
results:
description: PolicyReportResult provides result details
items:
description: PolicyReportResult provides the result for an individual
policy
properties:
category:
description: Category indicates policy category
type: string
message:
description: Description is a short user friendly message for
the policy rule
type: string
policy:
description: Policy is the name or identifier of the policy
type: string
properties:
additionalProperties:
type: string
description: Properties provides additional information for
the policy rule
type: object
resourceSelector:
description: SubjectSelector is an optional label selector for
checked Kubernetes resources. For example, a policy result
may apply to all pods that match a label. Either a Subject
or a SubjectSelector can be specified. If neither are provided,
the result is assumed to be for the policy report scope.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn,
Exists and DoesNotExist.
type: string
values:
description: values is an array of string values.
If the operator is In or NotIn, the values array
must be non-empty. If the operator is Exists or
DoesNotExist, the values array must be empty. This
array is replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
resources:
description: Subjects is an optional reference to the checked
Kubernetes resources
items:
description: "ObjectReference contains enough information
to let you inspect or modify the referred object. --- New
uses of this type are discouraged because of difficulty
describing its usage when embedded in APIs. 1. Ignored fields.
\ It includes many fields which are not generally honored.
\ For instance, ResourceVersion and FieldPath are both very
rarely valid in actual usage. 2. Invalid usage help. It
is impossible to add specific help for individual usage.
\ In most embedded usages, there are particular restrictions
like, \"must refer only to types A and B\" or \"UID not
honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation.
\ Because the usages are different, the validation rules
are different by usage, which makes it hard for users to
predict what will happen. 4. The fields are both imprecise
and overly precise. Kind is not a precise mapping to a
URL. This can produce ambiguity during interpretation and
require a REST mapping. In most cases, the dependency is
on the group,resource tuple and the version of the actual
struct is irrelevant. 5. We cannot easily change it. Because
this type is embedded in many locations, updates to this
type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n
Instead of using this type, create a locally provided and
used type that is well-focused on your reference. For example,
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
."
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that
triggered the event) or if no container name is specified
"spec.containers[2]" (container with index 2 in this
pod). This syntax is chosen only to have some well-defined
way of referencing a part of an object. TODO: this design
is not final and this field is subject to change in
the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
result:
description: Result indicates the outcome of the policy rule
execution
enum:
- pass
- fail
- warn
- error
- skip
type: string
rule:
description: Rule is the name or identifier of the rule within
the policy
type: string
scored:
description: Scored indicates if this result is scored
type: boolean
severity:
description: Severity indicates policy check result criticality
enum:
- critical
- high
- low
- medium
- info
type: string
source:
description: Source is an identifier for the policy engine that
manages this report
type: string
timestamp:
description: Timestamp indicates the time the result was found
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must
still have non-negative nanos values that count forward
in time. Must be from 0 to 999,999,999 inclusive. This
field may be limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z
to 9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
required:
- policy
type: object
type: array
summary:
description: PolicyReportSummary provides a summary of results
properties:
error:
description: Error provides the count of policies that could not
be evaluated
type: integer
fail:
description: Fail provides the count of policies whose requirements
were not met
type: integer
pass:
description: Pass provides the count of policies whose requirements
were met
type: integer
skip:
description: Skip indicates the count of policies that were not
selected for evaluation
type: integer
warn:
description: Warn provides the count of non-scored policies whose
requirements were not met
type: integer
type: object
required:
- owner
type: object
required:
- spec
type: object
served: true
storage: true
subresources: {}

View file

@ -0,0 +1,295 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.1-0.20220629131006-1878064c4cdf
creationTimestamp: null
name: backgroundscanreports.kyverno.io
spec:
group: kyverno.io
names:
kind: BackgroundScanReport
listKind: BackgroundScanReportList
plural: backgroundscanreports
shortNames:
- bgscanr
singular: backgroundscanreport
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.ownerReferences[0].kind
name: Kind
priority: 1
type: string
- jsonPath: .metadata.ownerReferences[0].name
name: Subject
priority: 1
type: string
- jsonPath: .spec.summary.pass
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: Skip
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1alpha2
schema:
openAPIV3Schema:
description: BackgroundScanReport is the Schema for the BackgroundScanReports
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
results:
description: PolicyReportResult provides result details
items:
description: PolicyReportResult provides the result for an individual
policy
properties:
category:
description: Category indicates policy category
type: string
message:
description: Description is a short user friendly message for
the policy rule
type: string
policy:
description: Policy is the name or identifier of the policy
type: string
properties:
additionalProperties:
type: string
description: Properties provides additional information for
the policy rule
type: object
resourceSelector:
description: SubjectSelector is an optional label selector for
checked Kubernetes resources. For example, a policy result
may apply to all pods that match a label. Either a Subject
or a SubjectSelector can be specified. If neither are provided,
the result is assumed to be for the policy report scope.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn,
Exists and DoesNotExist.
type: string
values:
description: values is an array of string values.
If the operator is In or NotIn, the values array
must be non-empty. If the operator is Exists or
DoesNotExist, the values array must be empty. This
array is replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
resources:
description: Subjects is an optional reference to the checked
Kubernetes resources
items:
description: "ObjectReference contains enough information
to let you inspect or modify the referred object. --- New
uses of this type are discouraged because of difficulty
describing its usage when embedded in APIs. 1. Ignored fields.
\ It includes many fields which are not generally honored.
\ For instance, ResourceVersion and FieldPath are both very
rarely valid in actual usage. 2. Invalid usage help. It
is impossible to add specific help for individual usage.
\ In most embedded usages, there are particular restrictions
like, \"must refer only to types A and B\" or \"UID not
honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation.
\ Because the usages are different, the validation rules
are different by usage, which makes it hard for users to
predict what will happen. 4. The fields are both imprecise
and overly precise. Kind is not a precise mapping to a
URL. This can produce ambiguity during interpretation and
require a REST mapping. In most cases, the dependency is
on the group,resource tuple and the version of the actual
struct is irrelevant. 5. We cannot easily change it. Because
this type is embedded in many locations, updates to this
type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n
Instead of using this type, create a locally provided and
used type that is well-focused on your reference. For example,
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
."
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that
triggered the event) or if no container name is specified
"spec.containers[2]" (container with index 2 in this
pod). This syntax is chosen only to have some well-defined
way of referencing a part of an object. TODO: this design
is not final and this field is subject to change in
the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
result:
description: Result indicates the outcome of the policy rule
execution
enum:
- pass
- fail
- warn
- error
- skip
type: string
rule:
description: Rule is the name or identifier of the rule within
the policy
type: string
scored:
description: Scored indicates if this result is scored
type: boolean
severity:
description: Severity indicates policy check result criticality
enum:
- critical
- high
- low
- medium
- info
type: string
source:
description: Source is an identifier for the policy engine that
manages this report
type: string
timestamp:
description: Timestamp indicates the time the result was found
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must
still have non-negative nanos values that count forward
in time. Must be from 0 to 999,999,999 inclusive. This
field may be limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z
to 9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
required:
- policy
type: object
type: array
summary:
description: PolicyReportSummary provides a summary of results
properties:
error:
description: Error provides the count of policies that could not
be evaluated
type: integer
fail:
description: Fail provides the count of policies whose requirements
were not met
type: integer
pass:
description: Pass provides the count of policies whose requirements
were met
type: integer
skip:
description: Skip indicates the count of policies that were not
selected for evaluation
type: integer
warn:
description: Warn provides the count of non-scored policies whose
requirements were not met
type: integer
type: object
type: object
required:
- spec
type: object
served: true
storage: true
subresources: {}

View file

@ -0,0 +1,332 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.1-0.20220629131006-1878064c4cdf
creationTimestamp: null
name: clusteradmissionreports.kyverno.io
spec:
group: kyverno.io
names:
kind: ClusterAdmissionReport
listKind: ClusterAdmissionReportList
plural: clusteradmissionreports
shortNames:
- cadmr
singular: clusteradmissionreport
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .scope.kind
name: Kind
priority: 1
type: string
- jsonPath: .scope.name
name: Subject
priority: 1
type: string
- jsonPath: .spec.summary.pass
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: Skip
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1alpha2
schema:
openAPIV3Schema:
description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
owner:
description: Owner is a reference to the report owner (e.g. a Deployment,
Namespace, or Node)
properties:
apiVersion:
description: API version of the referent.
type: string
blockOwnerDeletion:
description: If true, AND if the owner has the "foregroundDeletion"
finalizer, then the owner cannot be deleted from the key-value
store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion
for how the garbage collector interacts with this field and
enforces the foreground deletion. Defaults to false. To set
this field, a user needs "delete" permission of the owner, otherwise
422 (Unprocessable Entity) will be returned.
type: boolean
controller:
description: If true, this reference points to the managing controller.
type: boolean
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names'
type: string
uid:
description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids'
type: string
required:
- apiVersion
- kind
- name
- uid
type: object
x-kubernetes-map-type: atomic
results:
description: PolicyReportResult provides result details
items:
description: PolicyReportResult provides the result for an individual
policy
properties:
category:
description: Category indicates policy category
type: string
message:
description: Description is a short user friendly message for
the policy rule
type: string
policy:
description: Policy is the name or identifier of the policy
type: string
properties:
additionalProperties:
type: string
description: Properties provides additional information for
the policy rule
type: object
resourceSelector:
description: SubjectSelector is an optional label selector for
checked Kubernetes resources. For example, a policy result
may apply to all pods that match a label. Either a Subject
or a SubjectSelector can be specified. If neither are provided,
the result is assumed to be for the policy report scope.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn,
Exists and DoesNotExist.
type: string
values:
description: values is an array of string values.
If the operator is In or NotIn, the values array
must be non-empty. If the operator is Exists or
DoesNotExist, the values array must be empty. This
array is replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
resources:
description: Subjects is an optional reference to the checked
Kubernetes resources
items:
description: "ObjectReference contains enough information
to let you inspect or modify the referred object. --- New
uses of this type are discouraged because of difficulty
describing its usage when embedded in APIs. 1. Ignored fields.
\ It includes many fields which are not generally honored.
\ For instance, ResourceVersion and FieldPath are both very
rarely valid in actual usage. 2. Invalid usage help. It
is impossible to add specific help for individual usage.
\ In most embedded usages, there are particular restrictions
like, \"must refer only to types A and B\" or \"UID not
honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation.
\ Because the usages are different, the validation rules
are different by usage, which makes it hard for users to
predict what will happen. 4. The fields are both imprecise
and overly precise. Kind is not a precise mapping to a
URL. This can produce ambiguity during interpretation and
require a REST mapping. In most cases, the dependency is
on the group,resource tuple and the version of the actual
struct is irrelevant. 5. We cannot easily change it. Because
this type is embedded in many locations, updates to this
type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n
Instead of using this type, create a locally provided and
used type that is well-focused on your reference. For example,
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
."
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that
triggered the event) or if no container name is specified
"spec.containers[2]" (container with index 2 in this
pod). This syntax is chosen only to have some well-defined
way of referencing a part of an object. TODO: this design
is not final and this field is subject to change in
the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
result:
description: Result indicates the outcome of the policy rule
execution
enum:
- pass
- fail
- warn
- error
- skip
type: string
rule:
description: Rule is the name or identifier of the rule within
the policy
type: string
scored:
description: Scored indicates if this result is scored
type: boolean
severity:
description: Severity indicates policy check result criticality
enum:
- critical
- high
- low
- medium
- info
type: string
source:
description: Source is an identifier for the policy engine that
manages this report
type: string
timestamp:
description: Timestamp indicates the time the result was found
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must
still have non-negative nanos values that count forward
in time. Must be from 0 to 999,999,999 inclusive. This
field may be limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z
to 9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
required:
- policy
type: object
type: array
summary:
description: PolicyReportSummary provides a summary of results
properties:
error:
description: Error provides the count of policies that could not
be evaluated
type: integer
fail:
description: Fail provides the count of policies whose requirements
were not met
type: integer
pass:
description: Pass provides the count of policies whose requirements
were met
type: integer
skip:
description: Skip indicates the count of policies that were not
selected for evaluation
type: integer
warn:
description: Warn provides the count of non-scored policies whose
requirements were not met
type: integer
type: object
required:
- owner
type: object
required:
- spec
type: object
served: true
storage: true
subresources: {}

View file

@ -0,0 +1,295 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.1-0.20220629131006-1878064c4cdf
creationTimestamp: null
name: clusterbackgroundscanreports.kyverno.io
spec:
group: kyverno.io
names:
kind: ClusterBackgroundScanReport
listKind: ClusterBackgroundScanReportList
plural: clusterbackgroundscanreports
shortNames:
- cbgscanr
singular: clusterbackgroundscanreport
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.ownerReferences[0].kind
name: Kind
priority: 1
type: string
- jsonPath: .metadata.ownerReferences[0].name
name: Subject
priority: 1
type: string
- jsonPath: .spec.summary.pass
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: Skip
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1alpha2
schema:
openAPIV3Schema:
description: ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
results:
description: PolicyReportResult provides result details
items:
description: PolicyReportResult provides the result for an individual
policy
properties:
category:
description: Category indicates policy category
type: string
message:
description: Description is a short user friendly message for
the policy rule
type: string
policy:
description: Policy is the name or identifier of the policy
type: string
properties:
additionalProperties:
type: string
description: Properties provides additional information for
the policy rule
type: object
resourceSelector:
description: SubjectSelector is an optional label selector for
checked Kubernetes resources. For example, a policy result
may apply to all pods that match a label. Either a Subject
or a SubjectSelector can be specified. If neither are provided,
the result is assumed to be for the policy report scope.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn,
Exists and DoesNotExist.
type: string
values:
description: values is an array of string values.
If the operator is In or NotIn, the values array
must be non-empty. If the operator is Exists or
DoesNotExist, the values array must be empty. This
array is replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
resources:
description: Subjects is an optional reference to the checked
Kubernetes resources
items:
description: "ObjectReference contains enough information
to let you inspect or modify the referred object. --- New
uses of this type are discouraged because of difficulty
describing its usage when embedded in APIs. 1. Ignored fields.
\ It includes many fields which are not generally honored.
\ For instance, ResourceVersion and FieldPath are both very
rarely valid in actual usage. 2. Invalid usage help. It
is impossible to add specific help for individual usage.
\ In most embedded usages, there are particular restrictions
like, \"must refer only to types A and B\" or \"UID not
honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation.
\ Because the usages are different, the validation rules
are different by usage, which makes it hard for users to
predict what will happen. 4. The fields are both imprecise
and overly precise. Kind is not a precise mapping to a
URL. This can produce ambiguity during interpretation and
require a REST mapping. In most cases, the dependency is
on the group,resource tuple and the version of the actual
struct is irrelevant. 5. We cannot easily change it. Because
this type is embedded in many locations, updates to this
type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n
Instead of using this type, create a locally provided and
used type that is well-focused on your reference. For example,
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
."
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that
triggered the event) or if no container name is specified
"spec.containers[2]" (container with index 2 in this
pod). This syntax is chosen only to have some well-defined
way of referencing a part of an object. TODO: this design
is not final and this field is subject to change in
the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
result:
description: Result indicates the outcome of the policy rule
execution
enum:
- pass
- fail
- warn
- error
- skip
type: string
rule:
description: Rule is the name or identifier of the rule within
the policy
type: string
scored:
description: Scored indicates if this result is scored
type: boolean
severity:
description: Severity indicates policy check result criticality
enum:
- critical
- high
- low
- medium
- info
type: string
source:
description: Source is an identifier for the policy engine that
manages this report
type: string
timestamp:
description: Timestamp indicates the time the result was found
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must
still have non-negative nanos values that count forward
in time. Must be from 0 to 999,999,999 inclusive. This
field may be limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z
to 9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
required:
- policy
type: object
type: array
summary:
description: PolicyReportSummary provides a summary of results
properties:
error:
description: Error provides the count of policies that could not
be evaluated
type: integer
fail:
description: Fail provides the count of policies whose requirements
were not met
type: integer
pass:
description: Pass provides the count of policies whose requirements
were met
type: integer
skip:
description: Skip indicates the count of policies that were not
selected for evaluation
type: integer
warn:
description: Warn provides the count of non-scored policies whose
requirements were not met
type: integer
type: object
type: object
required:
- spec
type: object
served: true
storage: true
subresources: {}

View file

@ -20,7 +20,7 @@ spec:
- additionalPrinterColumns:
- jsonPath: .spec.background
name: Background
type: string
type: boolean
- jsonPath: .spec.validationFailureAction
name: Validate Action
type: string
@ -30,7 +30,7 @@ spec:
type: string
- jsonPath: .status.ready
name: Ready
type: string
type: boolean
name: v1
schema:
openAPIV3Schema:
@ -63,6 +63,7 @@ spec:
- One
type: string
background:
default: true
description: 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
@ -852,6 +853,55 @@ spec:
namespace:
description: Namespace specifies source resource namespace.
type: string
selector:
description: Selector is a label selector. Label keys
and values in `matchLabels`. wildcard characters are
not supported.
properties:
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are ANDed.
items:
description: A label selector requirement is a
selector that contains values, a key, and an
operator that relates the key and values.
properties:
key:
description: key is the label key that the
selector applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are
In, NotIn, Exists and DoesNotExist.
type: string
values:
description: values is an array of string
values. If the operator is In or NotIn,
the values array must be non-empty. If the
operator is Exists or DoesNotExist, the
values array must be empty. This array is
replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value}
pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is "In",
and the values array contains only "value". The
requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
data:
description: Data provides the resource declaration used
@ -2093,7 +2143,7 @@ spec:
properties:
annotationDomain:
description: AnnotationDomain is custom domain of annotation
for message nad signature. Default is "cosign.sigstore.dev".
for message and signature. Default is "cosign.sigstore.dev".
type: string
attestors:
description: Attestors specified the required attestors
@ -2317,24 +2367,31 @@ spec:
controlName:
description: 'ControlName specifies the name of
the Pod Security Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/'
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
type: string
images:
description: Images is a list of matching image
patterns. Each image is the image name consisting
of the registry address, repository, image,
and tag.
items:
type: string
type: array
restrictedField:
description: RestrictedField selects the field
for the given Pod Security Standard control.
When not set, all restricted fields for the
control are selected.
type: string
values:
description: Values defines the allowed values
that can be excluded.
description: '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.'
items:
type: string
type: array
@ -2751,6 +2808,7 @@ spec:
disable the validation checks.
type: boolean
validationFailureAction:
default: audit
description: 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
@ -3592,6 +3650,59 @@ spec:
description: Namespace specifies source resource
namespace.
type: string
selector:
description: Selector is a label selector. Label
keys and values in `matchLabels`. wildcard characters
are not supported.
properties:
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are
ANDed.
items:
description: A label selector requirement
is a selector that contains values, a key,
and an operator that relates the key and
values.
properties:
key:
description: key is the label key that
the selector applies to.
type: string
operator:
description: operator represents a key's
relationship to a set of values. Valid
operators are In, NotIn, Exists and
DoesNotExist.
type: string
values:
description: values is an array of string
values. If the operator is In or NotIn,
the values array must be non-empty.
If the operator is Exists or DoesNotExist,
the values array must be empty. This
array is replaced during a strategic
merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value}
pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is
"In", and the values array contains only "value".
The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
data:
description: Data provides the resource declaration
@ -4884,7 +4995,7 @@ spec:
properties:
annotationDomain:
description: AnnotationDomain is custom domain of
annotation for message nad signature. Default
annotation for message and signature. Default
is "cosign.sigstore.dev".
type: string
attestors:
@ -5115,24 +5226,32 @@ spec:
description: 'ControlName specifies the name
of the Pod Security Standard control. See:
https://kubernetes.io/docs/concepts/security/pod-security-standards/'
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
type: string
images:
description: Images is a list of matching
image patterns. Each image is the image
name consisting of the registry address,
repository, image, and tag.
items:
type: string
type: array
restrictedField:
description: RestrictedField selects the field
for the given Pod Security Standard control.
When not set, all restricted fields for
the control are selected.
type: string
values:
description: Values defines the allowed values
that can be excluded.
description: '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.'
items:
type: string
type: array
@ -5562,8 +5681,8 @@ spec:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
type FooStatus struct{ // Represents the observations of a foo's
current state. // Known .status.conditions.type are: \"Available\",
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
@ -5642,9 +5761,9 @@ spec:
- additionalPrinterColumns:
- jsonPath: .spec.background
name: Background
type: string
type: boolean
- jsonPath: .spec.validationFailureAction
name: Action
name: Validate Action
type: string
- jsonPath: .spec.failurePolicy
name: Failure Policy
@ -5652,7 +5771,7 @@ spec:
type: string
- jsonPath: .status.ready
name: Ready
type: string
type: boolean
name: v2beta1
schema:
openAPIV3Schema:
@ -5685,6 +5804,7 @@ spec:
- One
type: string
background:
default: true
description: 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
@ -6276,6 +6396,55 @@ spec:
namespace:
description: Namespace specifies source resource namespace.
type: string
selector:
description: Selector is a label selector. Label keys
and values in `matchLabels`. wildcard characters are
not supported.
properties:
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are ANDed.
items:
description: A label selector requirement is a
selector that contains values, a key, and an
operator that relates the key and values.
properties:
key:
description: key is the label key that the
selector applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are
In, NotIn, Exists and DoesNotExist.
type: string
values:
description: values is an array of string
values. If the operator is In or NotIn,
the values array must be non-empty. If the
operator is Exists or DoesNotExist, the
values array must be empty. This array is
replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value}
pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is "In",
and the values array contains only "value". The
requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
data:
description: Data provides the resource declaration used
@ -7487,7 +7656,7 @@ spec:
properties:
annotationDomain:
description: AnnotationDomain is custom domain of annotation
for message nad signature. Default is "cosign.sigstore.dev".
for message and signature. Default is "cosign.sigstore.dev".
type: string
attestors:
description: Attestors specified the required attestors
@ -7711,24 +7880,31 @@ spec:
controlName:
description: 'ControlName specifies the name of
the Pod Security Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/'
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
type: string
images:
description: Images is a list of matching image
patterns. Each image is the image name consisting
of the registry address, repository, image,
and tag.
items:
type: string
type: array
restrictedField:
description: RestrictedField selects the field
for the given Pod Security Standard control.
When not set, all restricted fields for the
control are selected.
type: string
values:
description: Values defines the allowed values
that can be excluded.
description: '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.'
items:
type: string
type: array
@ -8105,6 +8281,7 @@ spec:
disable the validation checks.
type: boolean
validationFailureAction:
default: audit
description: 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
@ -8946,6 +9123,59 @@ spec:
description: Namespace specifies source resource
namespace.
type: string
selector:
description: Selector is a label selector. Label
keys and values in `matchLabels`. wildcard characters
are not supported.
properties:
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are
ANDed.
items:
description: A label selector requirement
is a selector that contains values, a key,
and an operator that relates the key and
values.
properties:
key:
description: key is the label key that
the selector applies to.
type: string
operator:
description: operator represents a key's
relationship to a set of values. Valid
operators are In, NotIn, Exists and
DoesNotExist.
type: string
values:
description: values is an array of string
values. If the operator is In or NotIn,
the values array must be non-empty.
If the operator is Exists or DoesNotExist,
the values array must be empty. This
array is replaced during a strategic
merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value}
pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is
"In", and the values array contains only "value".
The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
data:
description: Data provides the resource declaration
@ -10238,7 +10468,7 @@ spec:
properties:
annotationDomain:
description: AnnotationDomain is custom domain of
annotation for message nad signature. Default
annotation for message and signature. Default
is "cosign.sigstore.dev".
type: string
attestors:
@ -10469,24 +10699,32 @@ spec:
description: 'ControlName specifies the name
of the Pod Security Standard control. See:
https://kubernetes.io/docs/concepts/security/pod-security-standards/'
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
type: string
images:
description: Images is a list of matching
image patterns. Each image is the image
name consisting of the registry address,
repository, image, and tag.
items:
type: string
type: array
restrictedField:
description: RestrictedField selects the field
for the given Pod Security Standard control.
When not set, all restricted fields for
the control are selected.
type: string
values:
description: Values defines the allowed values
that can be excluded.
description: '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.'
items:
type: string
type: array
@ -10916,8 +11154,8 @@ spec:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
type FooStatus struct{ // Represents the observations of a foo's
current state. // Known .status.conditions.type are: \"Available\",
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"

View file

@ -1,363 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.1-0.20220629131006-1878064c4cdf
creationTimestamp: null
name: clusterreportchangerequests.kyverno.io
spec:
group: kyverno.io
names:
kind: ClusterReportChangeRequest
listKind: ClusterReportChangeRequestList
plural: clusterreportchangerequests
shortNames:
- crcr
singular: clusterreportchangerequest
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .scope.kind
name: Kind
priority: 1
type: string
- jsonPath: .scope.name
name: Name
priority: 1
type: string
- jsonPath: .summary.pass
name: Pass
type: integer
- jsonPath: .summary.fail
name: Fail
type: integer
- jsonPath: .summary.warn
name: Warn
type: integer
- jsonPath: .summary.error
name: Error
type: integer
- jsonPath: .summary.skip
name: Skip
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha2
schema:
openAPIV3Schema:
description: ClusterReportChangeRequest is the Schema for the ClusterReportChangeRequests
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
results:
description: PolicyReportResult provides result details
items:
description: PolicyReportResult provides the result for an individual
policy
properties:
category:
description: Category indicates policy category
type: string
message:
description: Description is a short user friendly message for the
policy rule
type: string
policy:
description: Policy is the name or identifier of the policy
type: string
properties:
additionalProperties:
type: string
description: Properties provides additional information for the
policy rule
type: object
resourceSelector:
description: SubjectSelector is an optional label selector for checked
Kubernetes resources. For example, a policy result may apply to
all pods that match a label. Either a Subject or a SubjectSelector
can be specified. If neither are provided, the result is assumed
to be for the policy report scope.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that
contains values, a key, and an operator that relates the
key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn, Exists
and DoesNotExist.
type: string
values:
description: values is an array of string values. If the
operator is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. This array is replaced during a
strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A single
{key,value} in the matchLabels map is equivalent to an element
of matchExpressions, whose key field is "key", the operator
is "In", and the values array contains only "value". The requirements
are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
resources:
description: Subjects is an optional reference to the checked Kubernetes
resources
items:
description: 'ObjectReference contains enough information to let
you inspect or modify the referred object. --- New uses of this
type are discouraged because of difficulty describing its usage
when embedded in APIs. 1. Ignored fields. It includes many
fields which are not generally honored. For instance, ResourceVersion
and FieldPath are both very rarely valid in actual usage. 2.
Invalid usage help. It is impossible to add specific help for
individual usage. In most embedded usages, there are particular
restrictions like, "must refer only to types A and B" or "UID
not honored" or "name must be restricted". Those cannot be well
described when embedded. 3. Inconsistent validation. Because
the usages are different, the validation rules are different
by usage, which makes it hard for users to predict what will
happen. 4. The fields are both imprecise and overly precise. Kind
is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases,
the dependency is on the group,resource tuple and the version
of the actual struct is irrelevant. 5. We cannot easily change
it. Because this type is embedded in many locations, updates
to this type will affect numerous schemas. Don''t make new
APIs embed an underspecified API type they do not control. Instead
of using this type, create a locally provided and used type
that is well-focused on your reference. For example, ServiceReferences
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
.'
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part
of an object. TODO: this design is not final and this field
is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
result:
description: Result indicates the outcome of the policy rule execution
enum:
- pass
- fail
- warn
- error
- skip
type: string
rule:
description: Rule is the name or identifier of the rule within the
policy
type: string
scored:
description: Scored indicates if this result is scored
type: boolean
severity:
description: Severity indicates policy check result criticality
enum:
- critical
- high
- low
- medium
- info
type: string
source:
description: Source is an identifier for the policy engine that
manages this report
type: string
timestamp:
description: Timestamp indicates the time the result was found
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must still
have non-negative nanos values that count forward in time.
Must be from 0 to 999,999,999 inclusive. This field may be
limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
required:
- policy
type: object
type: array
scope:
description: Scope is an optional reference to the report scope (e.g.
a Deployment, Namespace, or Node)
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead of an entire
object, this string should contain a valid JSON/Go field access
statement, such as desiredState.manifest.containers[2]. For example,
if the object reference is to a container within a pod, this would
take on a value like: "spec.containers{name}" (where "name" refers
to the name of the container that triggered the event) or if no
container name is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to have some well-defined
way of referencing a part of an object. TODO: this design is not
final and this field is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference is
made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
scopeSelector:
description: ScopeSelector is an optional selector for multiple scopes
(e.g. Pods). Either one of, or none of, but not both of, Scope or ScopeSelector
should be specified.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that contains
values, a key, and an operator that relates the key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship to a set
of values. Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: values is an array of string values. If the operator
is In or NotIn, the values array must be non-empty. If the
operator is Exists or DoesNotExist, the values array must
be empty. This array is replaced during a strategic merge
patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A single {key,value}
in the matchLabels map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is "In", and the values array
contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
summary:
description: PolicyReportSummary provides a summary of results
properties:
error:
description: Error provides the count of policies that could not be
evaluated
type: integer
fail:
description: Fail provides the count of policies whose requirements
were not met
type: integer
pass:
description: Pass provides the count of policies whose requirements
were met
type: integer
skip:
description: Skip indicates the count of policies that were not selected
for evaluation
type: integer
warn:
description: Warn provides the count of non-scored policies whose
requirements were not met
type: integer
type: object
type: object
served: true
storage: true
subresources: {}

File diff suppressed because it is too large Load diff

View file

@ -1,363 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.1-0.20220629131006-1878064c4cdf
creationTimestamp: null
name: reportchangerequests.kyverno.io
spec:
group: kyverno.io
names:
kind: ReportChangeRequest
listKind: ReportChangeRequestList
plural: reportchangerequests
shortNames:
- rcr
singular: reportchangerequest
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .scope.kind
name: Kind
priority: 1
type: string
- jsonPath: .scope.name
name: Name
priority: 1
type: string
- jsonPath: .summary.pass
name: Pass
type: integer
- jsonPath: .summary.fail
name: Fail
type: integer
- jsonPath: .summary.warn
name: Warn
type: integer
- jsonPath: .summary.error
name: Error
type: integer
- jsonPath: .summary.skip
name: Skip
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha2
schema:
openAPIV3Schema:
description: ReportChangeRequest is the Schema for the ReportChangeRequests
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
results:
description: PolicyReportResult provides result details
items:
description: PolicyReportResult provides the result for an individual
policy
properties:
category:
description: Category indicates policy category
type: string
message:
description: Description is a short user friendly message for the
policy rule
type: string
policy:
description: Policy is the name or identifier of the policy
type: string
properties:
additionalProperties:
type: string
description: Properties provides additional information for the
policy rule
type: object
resourceSelector:
description: SubjectSelector is an optional label selector for checked
Kubernetes resources. For example, a policy result may apply to
all pods that match a label. Either a Subject or a SubjectSelector
can be specified. If neither are provided, the result is assumed
to be for the policy report scope.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that
contains values, a key, and an operator that relates the
key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn, Exists
and DoesNotExist.
type: string
values:
description: values is an array of string values. If the
operator is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. This array is replaced during a
strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A single
{key,value} in the matchLabels map is equivalent to an element
of matchExpressions, whose key field is "key", the operator
is "In", and the values array contains only "value". The requirements
are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
resources:
description: Subjects is an optional reference to the checked Kubernetes
resources
items:
description: 'ObjectReference contains enough information to let
you inspect or modify the referred object. --- New uses of this
type are discouraged because of difficulty describing its usage
when embedded in APIs. 1. Ignored fields. It includes many
fields which are not generally honored. For instance, ResourceVersion
and FieldPath are both very rarely valid in actual usage. 2.
Invalid usage help. It is impossible to add specific help for
individual usage. In most embedded usages, there are particular
restrictions like, "must refer only to types A and B" or "UID
not honored" or "name must be restricted". Those cannot be well
described when embedded. 3. Inconsistent validation. Because
the usages are different, the validation rules are different
by usage, which makes it hard for users to predict what will
happen. 4. The fields are both imprecise and overly precise. Kind
is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases,
the dependency is on the group,resource tuple and the version
of the actual struct is irrelevant. 5. We cannot easily change
it. Because this type is embedded in many locations, updates
to this type will affect numerous schemas. Don''t make new
APIs embed an underspecified API type they do not control. Instead
of using this type, create a locally provided and used type
that is well-focused on your reference. For example, ServiceReferences
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
.'
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part
of an object. TODO: this design is not final and this field
is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
result:
description: Result indicates the outcome of the policy rule execution
enum:
- pass
- fail
- warn
- error
- skip
type: string
rule:
description: Rule is the name or identifier of the rule within the
policy
type: string
scored:
description: Scored indicates if this result is scored
type: boolean
severity:
description: Severity indicates policy check result criticality
enum:
- critical
- high
- low
- medium
- info
type: string
source:
description: Source is an identifier for the policy engine that
manages this report
type: string
timestamp:
description: Timestamp indicates the time the result was found
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must still
have non-negative nanos values that count forward in time.
Must be from 0 to 999,999,999 inclusive. This field may be
limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
required:
- policy
type: object
type: array
scope:
description: Scope is an optional reference to the report scope (e.g.
a Deployment, Namespace, or Node)
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead of an entire
object, this string should contain a valid JSON/Go field access
statement, such as desiredState.manifest.containers[2]. For example,
if the object reference is to a container within a pod, this would
take on a value like: "spec.containers{name}" (where "name" refers
to the name of the container that triggered the event) or if no
container name is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to have some well-defined
way of referencing a part of an object. TODO: this design is not
final and this field is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference is
made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
scopeSelector:
description: ScopeSelector is an optional selector for multiple scopes
(e.g. Pods). Either one of, or none of, but not both of, Scope or ScopeSelector
should be specified.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that contains
values, a key, and an operator that relates the key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship to a set
of values. Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: values is an array of string values. If the operator
is In or NotIn, the values array must be non-empty. If the
operator is Exists or DoesNotExist, the values array must
be empty. This array is replaced during a strategic merge
patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A single {key,value}
in the matchLabels map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is "In", and the values array
contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
summary:
description: PolicyReportSummary provides a summary of results
properties:
error:
description: Error provides the count of policies that could not be
evaluated
type: integer
fail:
description: Fail provides the count of policies whose requirements
were not met
type: integer
pass:
description: Pass provides the count of policies whose requirements
were met
type: integer
skip:
description: Skip indicates the count of policies that were not selected
for evaluation
type: integer
warn:
description: Warn provides the count of non-scored policies whose
requirements were not met
type: integer
type: object
type: object
served: true
storage: true
subresources: {}

View file

@ -137,7 +137,7 @@ spec:
description: Subjects is an optional reference to the checked Kubernetes
resources
items:
description: 'ObjectReference contains enough information to let
description: "ObjectReference contains enough information to let
you inspect or modify the referred object. --- New uses of this
type are discouraged because of difficulty describing its usage
when embedded in APIs. 1. Ignored fields. It includes many
@ -145,23 +145,23 @@ spec:
and FieldPath are both very rarely valid in actual usage. 2.
Invalid usage help. It is impossible to add specific help for
individual usage. In most embedded usages, there are particular
restrictions like, "must refer only to types A and B" or "UID
not honored" or "name must be restricted". Those cannot be well
described when embedded. 3. Inconsistent validation. Because
restrictions like, \"must refer only to types A and B\" or \"UID
not honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation. Because
the usages are different, the validation rules are different
by usage, which makes it hard for users to predict what will
happen. 4. The fields are both imprecise and overly precise. Kind
is not a precise mapping to a URL. This can produce ambiguity
happen. 4. The fields are both imprecise and overly precise.
\ Kind is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases,
the dependency is on the group,resource tuple and the version
of the actual struct is irrelevant. 5. We cannot easily change
it. Because this type is embedded in many locations, updates
to this type will affect numerous schemas. Don''t make new
APIs embed an underspecified API type they do not control. Instead
to this type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n Instead
of using this type, create a locally provided and used type
that is well-focused on your reference. For example, ServiceReferences
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
.'
."
properties:
apiVersion:
description: API version of the referent.

View file

@ -136,7 +136,7 @@ spec:
description: Subjects is an optional reference to the checked Kubernetes
resources
items:
description: 'ObjectReference contains enough information to let
description: "ObjectReference contains enough information to let
you inspect or modify the referred object. --- New uses of this
type are discouraged because of difficulty describing its usage
when embedded in APIs. 1. Ignored fields. It includes many
@ -144,23 +144,23 @@ spec:
and FieldPath are both very rarely valid in actual usage. 2.
Invalid usage help. It is impossible to add specific help for
individual usage. In most embedded usages, there are particular
restrictions like, "must refer only to types A and B" or "UID
not honored" or "name must be restricted". Those cannot be well
described when embedded. 3. Inconsistent validation. Because
restrictions like, \"must refer only to types A and B\" or \"UID
not honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation. Because
the usages are different, the validation rules are different
by usage, which makes it hard for users to predict what will
happen. 4. The fields are both imprecise and overly precise. Kind
is not a precise mapping to a URL. This can produce ambiguity
happen. 4. The fields are both imprecise and overly precise.
\ Kind is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases,
the dependency is on the group,resource tuple and the version
of the actual struct is irrelevant. 5. We cannot easily change
it. Because this type is embedded in many locations, updates
to this type will affect numerous schemas. Don''t make new
APIs embed an underspecified API type they do not control. Instead
to this type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n Instead
of using this type, create a locally provided and used type
that is well-focused on your reference. For example, ServiceReferences
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
.'
."
properties:
apiVersion:
description: API version of the referent.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -49,13 +49,15 @@ metadata:
labels:
app: kyverno
rbac.authorization.k8s.io/aggregate-to-admin: "true"
name: kyverno:admin-reportchangerequest
name: kyverno:admin-reports
rules:
- apiGroups:
- kyverno.io
- kyverno.io
resources:
- reportchangerequests
- clusterreportchangerequests
- admissionreports
- clusteradmissionreports
- backgroundscanreports
- clusterbackgroundscanreports
verbs:
- create
- delete

View file

@ -29,10 +29,10 @@ rules:
- generaterequests/status
- updaterequests
- updaterequests/status
- reportchangerequests
- reportchangerequests/status
- clusterreportchangerequests
- clusterreportchangerequests/status
- admissionreports
- clusteradmissionreports
- backgroundscanreports
- clusterbackgroundscanreports
verbs:
- create
- delete

View file

@ -1,6 +1,25 @@
apiVersion: v1
data:
resourceFilters: '[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][*,kyverno,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][SelfSubjectAccessReview,*,*][*,kyverno,kyverno*][Binding,*,*][ReplicaSet,*,*][ReportChangeRequest,*,*][ClusterReportChangeRequest,*,*][PolicyReport,*,*][ClusterPolicyReport,*,*]'
resourceFilters: >
[Event,*,*]
[*,kube-system,*]
[*,kube-public,*]
[*,kube-node-lease,*]
[*,kyverno,*]
[Node,*,*]
[APIService,*,*]
[TokenReview,*,*]
[SubjectAccessReview,*,*]
[SelfSubjectAccessReview,*,*]
[*,kyverno,kyverno*]
[Binding,*,*]
[ReplicaSet,*,*]
[AdmissionReport,*,*]
[ClusterAdmissionReport,*,*]
[BackgroundScanReport,*,*]
[ClusterBackgroundScanReport,*,*]
[PolicyReport,*,*]
[ClusterPolicyReport,*,*]
webhooks: '[{"namespaceSelector": {"matchExpressions": [{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["kyverno"]}]}}]'
excludeGroupRole: 'system:serviceaccounts:kube-system,system:nodes,system:kube-scheduler'
generateSuccessEvents: 'false'

View file

@ -2,4 +2,13 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./release
- ./bundle/
transformers:
- labels.yaml
images:
- name: ghcr.io/kyverno/kyverno
newTag: latest
- name: ghcr.io/kyverno/kyvernopre
newTag: latest

View file

@ -63,6 +63,10 @@ spec:
env:
- name: METRICS_CONFIG
value: kyverno-metrics
- name: KYVERNO_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KYVERNO_NAMESPACE
valueFrom:
fieldRef:

File diff suppressed because it is too large Load diff

View file

@ -2,13 +2,13 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../bundle/
- $TOP_PATH/bundle/
transformers:
- labels.yaml
images:
- name: ghcr.io/kyverno/kyverno
newTag: latest
newTag: $VERSION
- name: ghcr.io/kyverno/kyvernopre
newTag: latest
newTag: $VERSION

View file

@ -0,0 +1,13 @@
---
apiVersion: builtin
kind: LabelTransformer
metadata:
name: labelTransformer
labels:
app.kubernetes.io/version: $VERSION
fieldSpecs:
- path: metadata/labels
create: true
- kind: Deployment
path: spec/template/metadata/labels
create: true

View file

@ -0,0 +1,11 @@
# Policy cache controller
## Attributes
This controller runs on all kyverno instances.
## Purpose
The policy cache controller watches instances of `Policy` and `ClusterPolicy` registered in the cluster and updates the policy cache accordingly.
The policy cache is used at admission time to lookup policies that need to be considered depending on the resource being processed.

View file

@ -2321,7 +2321,7 @@ string
</td>
<td>
<em>(Optional)</em>
<p>AnnotationDomain is custom domain of annotation for message nad signature. Default is &ldquo;cosign.sigstore.dev&rdquo;.</p>
<p>AnnotationDomain is custom domain of annotation for message and signature. Default is &ldquo;cosign.sigstore.dev&rdquo;.</p>
</td>
</tr>
<tr>
@ -2658,33 +2658,10 @@ See: <a href="https://kubernetes.io/docs/concepts/security/pod-security-standard
</td>
<td>
<em>(Optional)</em>
<p>Images is a list of matching image patterns.
Each image is the image name consisting of the registry address, repository, image, and tag.</p>
</td>
</tr>
<tr>
<td>
<code>restrictedField</code><br/>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>RestrictedField selects the field for the given Pod Security Standard control.
When not set, all restricted fields for the control are selected.</p>
</td>
</tr>
<tr>
<td>
<code>values</code><br/>
<em>
[]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Values defines the allowed values that can be excluded.</p>
<p>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 (&lsquo;*&rsquo; and &lsquo;?&rsquo;) are allowed. See: <a href="https://kubernetes.io/docs/concepts/containers/images">https://kubernetes.io/docs/concepts/containers/images</a>.</p>
</td>
</tr>
</tbody>

View file

@ -28,15 +28,19 @@ background-color: #1589dd;
</p>
Resource Types:
<ul><li>
<a href="#kyverno.io/v1alpha2.ClusterReportChangeRequest">ClusterReportChangeRequest</a>
<a href="#kyverno.io/v1alpha2.AdmissionReport">AdmissionReport</a>
</li><li>
<a href="#kyverno.io/v1alpha2.ReportChangeRequest">ReportChangeRequest</a>
<a href="#kyverno.io/v1alpha2.BackgroundScanReport">BackgroundScanReport</a>
</li><li>
<a href="#kyverno.io/v1alpha2.ClusterAdmissionReport">ClusterAdmissionReport</a>
</li><li>
<a href="#kyverno.io/v1alpha2.ClusterBackgroundScanReport">ClusterBackgroundScanReport</a>
</li></ul>
<hr />
<h3 id="kyverno.io/v1alpha2.ClusterReportChangeRequest">ClusterReportChangeRequest
<h3 id="kyverno.io/v1alpha2.AdmissionReport">AdmissionReport
</h3>
<p>
<p>ClusterReportChangeRequest is the Schema for the ClusterReportChangeRequests API</p>
<p>AdmissionReport is the Schema for the AdmissionReports API</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
@ -61,7 +65,7 @@ kyverno.io/v1alpha2
<code>kind</code><br/>
string
</td>
<td><code>ClusterReportChangeRequest</code></td>
<td><code>AdmissionReport</code></td>
</tr>
<tr>
<td>
@ -79,31 +83,362 @@ Refer to the Kubernetes API documentation for the fields of the
</tr>
<tr>
<td>
<code>scope</code><br/>
<code>spec</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectreference-v1-core">
Kubernetes core/v1.ObjectReference
<a href="#kyverno.io/v1alpha2.AdmissionReportSpec">
AdmissionReportSpec
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Scope is an optional reference to the report scope (e.g. a Deployment, Namespace, or Node)</p>
<br/>
<br/>
<table class="table table-striped">
<tr>
<td>
<code>owner</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#ownerreference-v1-meta">
Kubernetes meta/v1.OwnerReference
</a>
</em>
</td>
<td>
<p>Owner is a reference to the report owner (e.g. a Deployment, Namespace, or Node)</p>
</td>
</tr>
<tr>
<td>
<code>scopeSelector</code><br/>
<code>summary</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#labelselector-v1-meta">
Kubernetes meta/v1.LabelSelector
</a>
github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
</em>
</td>
<td>
<em>(Optional)</em>
<p>ScopeSelector is an optional selector for multiple scopes (e.g. Pods).
Either one of, or none of, but not both of, Scope or ScopeSelector should be specified.</p>
<p>PolicyReportSummary provides a summary of results</p>
</td>
</tr>
<tr>
<td>
<code>results</code><br/>
<em>
[]github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportResult
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportResult provides result details</p>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1alpha2.BackgroundScanReport">BackgroundScanReport
</h3>
<p>
<p>BackgroundScanReport is the Schema for the BackgroundScanReports API</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>apiVersion</code><br/>
string</td>
<td>
<code>
kyverno.io/v1alpha2
</code>
</td>
</tr>
<tr>
<td>
<code>kind</code><br/>
string
</td>
<td><code>BackgroundScanReport</code></td>
</tr>
<tr>
<td>
<code>metadata</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta">
Kubernetes meta/v1.ObjectMeta
</a>
</em>
</td>
<td>
Refer to the Kubernetes API documentation for the fields of the
<code>metadata</code> field.
</td>
</tr>
<tr>
<td>
<code>spec</code><br/>
<em>
<a href="#kyverno.io/v1alpha2.BackgroundScanReportSpec">
BackgroundScanReportSpec
</a>
</em>
</td>
<td>
<br/>
<br/>
<table class="table table-striped">
<tr>
<td>
<code>summary</code><br/>
<em>
github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportSummary provides a summary of results</p>
</td>
</tr>
<tr>
<td>
<code>results</code><br/>
<em>
[]github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportResult
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportResult provides result details</p>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1alpha2.ClusterAdmissionReport">ClusterAdmissionReport
</h3>
<p>
<p>ClusterAdmissionReport is the Schema for the ClusterAdmissionReports API</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>apiVersion</code><br/>
string</td>
<td>
<code>
kyverno.io/v1alpha2
</code>
</td>
</tr>
<tr>
<td>
<code>kind</code><br/>
string
</td>
<td><code>ClusterAdmissionReport</code></td>
</tr>
<tr>
<td>
<code>metadata</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta">
Kubernetes meta/v1.ObjectMeta
</a>
</em>
</td>
<td>
Refer to the Kubernetes API documentation for the fields of the
<code>metadata</code> field.
</td>
</tr>
<tr>
<td>
<code>spec</code><br/>
<em>
<a href="#kyverno.io/v1alpha2.AdmissionReportSpec">
AdmissionReportSpec
</a>
</em>
</td>
<td>
<br/>
<br/>
<table class="table table-striped">
<tr>
<td>
<code>owner</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#ownerreference-v1-meta">
Kubernetes meta/v1.OwnerReference
</a>
</em>
</td>
<td>
<p>Owner is a reference to the report owner (e.g. a Deployment, Namespace, or Node)</p>
</td>
</tr>
<tr>
<td>
<code>summary</code><br/>
<em>
github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportSummary provides a summary of results</p>
</td>
</tr>
<tr>
<td>
<code>results</code><br/>
<em>
[]github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportResult
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportResult provides result details</p>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1alpha2.ClusterBackgroundScanReport">ClusterBackgroundScanReport
</h3>
<p>
<p>ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports API</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>apiVersion</code><br/>
string</td>
<td>
<code>
kyverno.io/v1alpha2
</code>
</td>
</tr>
<tr>
<td>
<code>kind</code><br/>
string
</td>
<td><code>ClusterBackgroundScanReport</code></td>
</tr>
<tr>
<td>
<code>metadata</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta">
Kubernetes meta/v1.ObjectMeta
</a>
</em>
</td>
<td>
Refer to the Kubernetes API documentation for the fields of the
<code>metadata</code> field.
</td>
</tr>
<tr>
<td>
<code>spec</code><br/>
<em>
<a href="#kyverno.io/v1alpha2.BackgroundScanReportSpec">
BackgroundScanReportSpec
</a>
</em>
</td>
<td>
<br/>
<br/>
<table class="table table-striped">
<tr>
<td>
<code>summary</code><br/>
<em>
github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportSummary provides a summary of results</p>
</td>
</tr>
<tr>
<td>
<code>results</code><br/>
<em>
[]github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportResult
</em>
</td>
<td>
<em>(Optional)</em>
<p>PolicyReportResult provides result details</p>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1alpha2.AdmissionReportSpec">AdmissionReportSpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v1alpha2.AdmissionReport">AdmissionReport</a>,
<a href="#kyverno.io/v1alpha2.ClusterAdmissionReport">ClusterAdmissionReport</a>)
</p>
<p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>owner</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#ownerreference-v1-meta">
Kubernetes meta/v1.OwnerReference
</a>
</em>
</td>
<td>
<p>Owner is a reference to the report owner (e.g. a Deployment, Namespace, or Node)</p>
</td>
</tr>
<tr>
@ -133,10 +468,14 @@ github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1alpha2.ReportChangeRequest">ReportChangeRequest
<h3 id="kyverno.io/v1alpha2.BackgroundScanReportSpec">BackgroundScanReportSpec
</h3>
<p>
<p>ReportChangeRequest is the Schema for the ReportChangeRequests API</p>
(<em>Appears on:</em>
<a href="#kyverno.io/v1alpha2.BackgroundScanReport">BackgroundScanReport</a>,
<a href="#kyverno.io/v1alpha2.ClusterBackgroundScanReport">ClusterBackgroundScanReport</a>)
</p>
<p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
@ -148,66 +487,6 @@ github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
<tbody>
<tr>
<td>
<code>apiVersion</code><br/>
string</td>
<td>
<code>
kyverno.io/v1alpha2
</code>
</td>
</tr>
<tr>
<td>
<code>kind</code><br/>
string
</td>
<td><code>ReportChangeRequest</code></td>
</tr>
<tr>
<td>
<code>metadata</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectmeta-v1-meta">
Kubernetes meta/v1.ObjectMeta
</a>
</em>
</td>
<td>
Refer to the Kubernetes API documentation for the fields of the
<code>metadata</code> field.
</td>
</tr>
<tr>
<td>
<code>scope</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#objectreference-v1-core">
Kubernetes core/v1.ObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Scope is an optional reference to the report scope (e.g. a Deployment, Namespace, or Node)</p>
</td>
</tr>
<tr>
<td>
<code>scopeSelector</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#labelselector-v1-meta">
Kubernetes meta/v1.LabelSelector
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ScopeSelector is an optional selector for multiple scopes (e.g. Pods).
Either one of, or none of, but not both of, Scope or ScopeSelector should be specified.</p>
</td>
</tr>
<tr>
<td>
<code>summary</code><br/>
<em>
github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
@ -233,6 +512,11 @@ github.com/kyverno/kyverno/api/policyreport/v1alpha2.PolicyReportSummary
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1alpha2.ReportInterface">ReportInterface
</h3>
<p>
<p>ReportInterface abstracts the concrete report change request type</p>
</p>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>

View file

@ -444,6 +444,18 @@ Defaults to &ldquo;false&rdquo; if not specified.</p>
</table>
</td>
</tr>
<tr>
<td>
<code>status</code><br/>
<em>
github.com/kyverno/kyverno/api/kyverno/v1.PolicyStatus
</em>
</td>
<td>
<em>(Optional)</em>
<p>Status contains policy runtime data.</p>
</td>
</tr>
</tbody>
</table>
<hr />

233
go.mod
View file

@ -3,64 +3,41 @@ module github.com/kyverno/kyverno
go 1.18
require (
github.com/IGLOU-EU/go-wildcard v1.0.3
github.com/aquilax/truncate v1.0.0
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20221004211355-a250ad2ca1e3
github.com/blang/semver/v4 v4.0.0
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21
github.com/cornelk/hashmap v1.0.1
github.com/dchest/siphash v1.2.1 // indirect
github.com/distribution/distribution v2.7.1+incompatible
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/chrismellard/docker-credential-acr-env v0.0.0-20221002210726-e883f69e0206
github.com/distribution/distribution v2.8.1+incompatible
github.com/evanphx/json-patch v5.6.0+incompatible
github.com/evanphx/json-patch/v5 v5.6.0
github.com/fatih/color v1.13.0
github.com/gardener/controller-manager-library v0.2.0
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/go-git/go-billy/v5 v5.0.0
github.com/go-git/go-git/v5 v5.2.0
github.com/go-git/go-billy/v5 v5.3.1
github.com/go-git/go-git/v5 v5.4.2
github.com/go-logr/logr v1.2.3
github.com/go-logr/zapr v1.2.3
github.com/google/gnostic v0.6.9
github.com/google/go-containerregistry v0.11.0
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20220301182634-bfe2ffc6b6bd
github.com/googleapis/gnostic v0.5.5
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20220927211808-7268da01c46e
github.com/in-toto/in-toto-golang v0.4.0
github.com/jmespath/go-jmespath v0.4.0
github.com/jmoiron/jsonq v0.0.0-20150511023944-e874b168d07e
github.com/julienschmidt/httprouter v1.3.0
github.com/kataras/tablewriter v0.0.0-20180708051242-e063d29b7c23
github.com/kyverno/go-wildcard v1.0.5
github.com/lensesio/tableprinter v0.0.0-20201125135848-89e81fc956e7
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a
github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/onsi/gomega v1.21.1
github.com/orcaman/concurrent-map/v2 v2.0.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.13.0 // indirect
github.com/sigstore/cosign v1.11.1
github.com/sigstore/sigstore v1.4.0
github.com/sigstore/cosign v1.12.1
github.com/sigstore/k8s-manifest-sigstore v0.4.1
github.com/sigstore/sigstore v1.4.2
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.8.0
github.com/xanzy/ssh-agent v0.3.0 // indirect
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools v2.2.0+incompatible
k8s.io/api v0.23.5
k8s.io/apiextensions-apiserver v0.23.4
k8s.io/apimachinery v0.23.5
k8s.io/cli-runtime v0.23.5
k8s.io/client-go v0.23.5
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf
k8s.io/pod-security-admission v0.23.0
sigs.k8s.io/controller-runtime v0.11.0
sigs.k8s.io/kustomize/api v0.11.2
sigs.k8s.io/kustomize/kyaml v0.13.3
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/jmoiron/jsonq v0.0.0-20150511023944-e874b168d07e
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea
go.opentelemetry.io/otel v1.7.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.30.0
@ -74,55 +51,83 @@ require (
go.opentelemetry.io/otel/trace v1.7.0
go.uber.org/automaxprocs v1.5.1
go.uber.org/multierr v1.8.0
go.uber.org/zap v1.23.0
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
golang.org/x/exp v0.0.0-20221006183845-316c7553db56
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b
google.golang.org/grpc v1.48.0
google.golang.org/grpc v1.50.0
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools v2.2.0+incompatible
k8s.io/api v0.25.2
k8s.io/apiextensions-apiserver v0.25.2
k8s.io/apimachinery v0.25.2
k8s.io/cli-runtime v0.25.2
k8s.io/client-go v0.25.2
k8s.io/klog/v2 v2.80.1
k8s.io/kube-openapi v0.0.0-20220928191237-829ce0c27909
k8s.io/pod-security-admission v0.25.2
sigs.k8s.io/controller-runtime v0.13.0
sigs.k8s.io/kustomize/api v0.12.1
sigs.k8s.io/kustomize/kyaml v0.13.9
sigs.k8s.io/yaml v1.3.0
)
require github.com/sigstore/k8s-manifest-sigstore v0.3.1-0.20220810053329-14f7cab4fd52
require (
bitbucket.org/creachadair/shell v0.0.7 // indirect
cloud.google.com/go v0.103.0 // indirect
cloud.google.com/go/compute v1.7.0 // indirect
cloud.google.com/go/iam v0.3.0 // indirect
cloud.google.com/go/compute v1.10.0 // indirect
cloud.google.com/go/iam v0.5.0 // indirect
cloud.google.com/go/kms v1.4.0 // indirect
cuelang.org/go v0.4.3 // indirect
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect
github.com/Azure/azure-sdk-for-go v66.0.0+incompatible // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20210707164159-52430bf6b52c // indirect
github.com/ThalesIgnite/crypto11 v1.2.5 // indirect
github.com/agnivade/levenshtein v1.0.1 // indirect
github.com/armon/go-metrics v0.4.0 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // 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 v0.0.0-20190504072949-9472017b5c68 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect
github.com/alibabacloud-go/openapi-util v0.0.11 // indirect
github.com/alibabacloud-go/tea v1.1.19 // indirect
github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
github.com/aliyun/credentials-go v1.2.4 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/aws/aws-sdk-go-v2 v1.16.11 // indirect
github.com/aws/aws-sdk-go-v2/config v1.17.1 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.12.14 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.15.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.18.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.11.17 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.16.13 // indirect
github.com/aws/smithy-go v1.12.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.16.16 // indirect
github.com/aws/aws-sdk-go-v2/config v1.17.8 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.12.21 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.17.18 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.13.17 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.18.11 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 // indirect
github.com/aws/smithy-go v1.13.3 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
@ -131,13 +136,13 @@ require (
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/clbanning/mxj/v2 v2.5.6 // indirect
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect
github.com/cockroachdb/apd/v2 v2.0.1 // indirect
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/containerd/stargz-snapshotter/estargz v0.12.0 // indirect
github.com/coreos/go-oidc/v3 v3.2.0 // indirect
github.com/coreos/go-oidc/v3 v3.4.0 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
@ -148,18 +153,17 @@ require (
github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v20.10.17+incompatible // indirect
github.com/docker/docker-credential-helpers v0.6.4 // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/emicklei/proto v1.6.15 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect
github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/fullstorydev/grpcurl v1.8.6 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/fullstorydev/grpcurl v1.8.7 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
@ -180,24 +184,25 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/certificate-transparency-go v1.1.3 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-github/v45 v45.2.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/trillian v1.4.1 // indirect
github.com/google/trillian v1.5.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
github.com/googleapis/gax-go/v2 v2.4.0 // indirect
github.com/googleapis/gax-go/v2 v2.5.1 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
@ -218,10 +223,10 @@ require (
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/vault/api v1.7.2 // indirect
github.com/hashicorp/vault/sdk v0.5.3 // indirect
github.com/hashicorp/vault/api v1.8.0 // indirect
github.com/hashicorp/vault/sdk v0.6.0 // indirect
github.com/hashicorp/yamux v0.1.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect
@ -231,7 +236,7 @@ require (
github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/klauspost/compress v1.15.8 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/letsencrypt/boulder v0.0.0-20220723181115-27de4befb95e // indirect
@ -241,35 +246,35 @@ require (
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/mozillazg/docker-credential-acr-helper v0.3.0 // indirect
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect
github.com/open-policy-agent/gatekeeper v0.0.0-20210824170141-dd97b8a7e966 // indirect
github.com/open-policy-agent/opa v0.43.0 // indirect
github.com/open-policy-agent/opa v0.44.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.13.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
@ -277,7 +282,6 @@ require (
github.com/r3labs/diff v1.1.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74 // indirect
@ -286,7 +290,7 @@ require (
github.com/sergi/go-diff v1.2.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/sigstore/fulcio v0.5.3 // indirect
github.com/sigstore/rekor v0.11.0 // indirect
github.com/sigstore/rekor v0.12.1-0.20220915152154-4bb6f441c1b2 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/soheilhy/cmux v0.1.5 // indirect
@ -294,25 +298,27 @@ require (
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.12.0 // indirect
github.com/spf13/viper v1.13.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.1.1 // indirect
github.com/subosito/gotenv v1.3.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/tektoncd/chains v0.3.0 // indirect
github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 // indirect
github.com/thales-e-security/pool v0.0.2 // indirect
github.com/theupdateframework/go-tuf v0.3.1 // indirect
github.com/theupdateframework/go-tuf v0.5.1-0.20220920170306-f237d7ca5b42 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/transparency-dev/merkle v0.0.1 // indirect
github.com/urfave/cli v1.22.7 // indirect
github.com/vbatts/tar-split v0.11.2 // indirect
github.com/vektah/gqlparser/v2 v2.4.6 // indirect
github.com/xanzy/go-gitlab v0.73.1 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
github.com/xlab/treeprint v1.1.0 // indirect
github.com/yashtewari/glob-intersection v0.1.0 // indirect
github.com/zeebo/errs v1.2.2 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
@ -334,19 +340,17 @@ require (
go.opentelemetry.io/proto/otlp v0.16.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/zap v1.22.0 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 // indirect
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/tools v0.1.11 // indirect
google.golang.org/api v0.93.0 // indirect
golang.org/x/net v0.0.0-20221004154528-8021a29435af // indirect
golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1 // indirect
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 // indirect
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 // indirect
golang.org/x/term v0.0.0-20220919170432-7a66f970e087 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/api v0.98.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220805133916-01dd62135a58 // indirect
google.golang.org/genproto v0.0.0-20220930163606-c98284e70a91 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
@ -354,18 +358,17 @@ require (
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
k8s.io/component-base v0.23.5 // indirect
k8s.io/kubectl v0.23.5 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
k8s.io/component-base v0.25.2 // indirect
k8s.io/kubectl v0.25.2 // indirect
k8s.io/utils v0.0.0-20220922133306-665eaaec4324 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/release-utils v0.7.3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)
replace (
github.com/apache/thrift => github.com/apache/thrift v0.14.0
github.com/buger/jsonparser => github.com/buger/jsonparser v1.1.1
github.com/containerd/containerd => github.com/containerd/containerd v1.5.9
github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.1
github.com/docker/cli => github.com/docker/cli v20.10.9+incompatible
github.com/evanphx/json-patch/v5 => github.com/kyverno/json-patch/v5 v5.5.1-0.20210915204938-7578f4ee9c77

1114
go.sum

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
package auth
import "sigs.k8s.io/controller-runtime/pkg/log"
import "github.com/kyverno/kyverno/pkg/logging"
var logger = log.Log.WithName("auth")
var logger = logging.WithName("auth")

View file

@ -220,12 +220,16 @@ func generateRules(spec *kyvernov1.Spec, controllers string) []kyvernov1.Rule {
if genRule := createRule(generateRuleForControllers(&spec.Rules[i], stripCronJob(controllers))); genRule != nil {
if convRule, err := convertRule(*genRule, "Pod"); err == nil {
rules = append(rules, *convRule)
} else {
logger.Error(err, "failed to create rule")
}
}
// handle CronJob, it appends an additional rule
if genRule := createRule(generateCronJobRule(&spec.Rules[i], controllers)); genRule != nil {
if convRule, err := convertRule(*genRule, "Cronjob"); err == nil {
rules = append(rules, *convRule)
} else {
logger.Error(err, "failed to create Cronjob rule")
}
}
}

View file

@ -3,7 +3,6 @@ package autogen
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -228,6 +227,11 @@ func Test_GetSupportedControllers(t *testing.T) {
policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test"},"spec":{"rules":[{"name":"require-network-policy","match":{"resources":{"kinds":["Pod"]}},"validate":{"message":"testpolicy","podSecurity": {"level": "baseline","version":"v1.24","exclude":[{"controlName":"SELinux","restrictedField":"spec.containers[*].securityContext.seLinuxOptions.role","images":["nginx"],"values":["baz"]}, {"controlName":"SELinux","restrictedField":"spec.initContainers[*].securityContext.seLinuxOptions.role","images":["nodejs"],"values":["init-baz"]}]}}}]}}`),
expectedControllers: PodControllers,
},
{
name: "rule-with-validate-podsecurity",
policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"pod-security"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"restricted","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"validate":{"podSecurity":{"level":"restricted","version":"v1.24"}}}]}}`),
expectedControllers: PodControllers,
},
}
for _, test := range testCases {
@ -294,7 +298,7 @@ func Test_Any(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
@ -332,7 +336,7 @@ func Test_All(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
@ -371,7 +375,7 @@ func Test_Exclude(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
@ -405,7 +409,7 @@ func Test_CronJobOnly(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
@ -435,7 +439,7 @@ func Test_ForEachPod(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/policy/mutate/policy_mutate_pod_foreach_with_context.yaml")
file, err := os.ReadFile(baseDir + "/test/policy/mutate/policy_mutate_pod_foreach_with_context.yaml")
if err != nil {
t.Log(err)
}
@ -470,7 +474,7 @@ func Test_CronJob_hasExclude(t *testing.T) {
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
@ -507,7 +511,7 @@ func Test_CronJobAndDeployment(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
@ -538,7 +542,7 @@ func Test_UpdateVariablePath(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/best_practices/select-secrets.yaml")
file, err := os.ReadFile(baseDir + "/test/best_practices/select-secrets.yaml")
if err != nil {
t.Log(err)
}
@ -568,7 +572,7 @@ func Test_Deny(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/policy/deny/policy.yaml")
file, err := os.ReadFile(baseDir + "/test/policy/deny/policy.yaml")
if err != nil {
t.Log(err)
}
@ -602,37 +606,6 @@ func Test_Deny(t *testing.T) {
}
}
func Test_ValidatePodSecurity(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
file, err := ioutil.ReadFile(baseDir + "/test/policy/validate/enforce-baseline-exclude-selinuxoptions.yaml")
if err != nil {
t.Log(err)
}
policies, err := yamlutils.GetPolicy(file)
if err != nil {
t.Log(err)
}
policy := policies[0]
spec := policy.GetSpec()
rulePatches, errs := GenerateRulePatches(spec, PodControllers)
if len(errs) != 0 {
t.Log(errs)
}
expectedPatches := [][]byte{
[]byte(`{"path":"/spec/rules/1","op":"add","value":{"name":"autogen-enforce-baseline-exclude-se-linux-options","match":{"any":[{"resources":{"kinds":["DaemonSet","Deployment","Job","StatefulSet"],"namespaces":["privileged-pss-with-kyverno"]}}],"resources":{}},"validate":{"podSecurity":{"level":"baseline","version":"v1.24","exclude":[{"controlName":"SELinux","images":["nginx"],"restrictedField":"spec.template.spec.containers[*].securityContext.seLinuxOptions.role","values":["baz"]},{"controlName":"SELinux","images":["nodejs"],"restrictedField":"spec.template.spec.initContainers[*].securityContext.seLinuxOptions.role","values":["init-bazo"]}]}}}}`),
[]byte(`{"path":"/spec/rules/2","op":"add","value":{"name":"autogen-cronjob-enforce-baseline-exclude-se-linux-options","match":{"any":[{"resources":{"kinds":["CronJob"],"namespaces":["privileged-pss-with-kyverno"]}}],"resources":{}},"validate":{"podSecurity":{"level":"baseline","version":"v1.24","exclude":[{"controlName":"SELinux","images":["nginx"],"restrictedField":"spec.jobTemplate.spec.template.spec.containers[*].securityContext.seLinuxOptions.role","values":["baz"]},{"controlName":"SELinux","images":["nodejs"],"restrictedField":"spec.jobTemplate.spec.template.spec.initContainers[*].securityContext.seLinuxOptions.role","values":["init-bazo"]}]}}}}`),
}
for i, ep := range expectedPatches {
assert.Equal(t, string(rulePatches[i]), string(ep),
fmt.Sprintf("unexpected patch: %s\nexpected: %s", rulePatches[i], ep))
}
}
func Test_ComputeRules(t *testing.T) {
intPtr := func(i int) *int { return &i }
testCases := []struct {
@ -817,3 +790,13 @@ kA==
assert.DeepEqual(t, test.expectedRules, rules)
}
}
func Test_PodSecurityWithNoExceptions(t *testing.T) {
policy := []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"pod-security"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"restricted","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"validate":{"podSecurity":{"level":"restricted","version":"v1.24"}}}]}}`)
policies, err := yamlutils.GetPolicy([]byte(policy))
assert.NilError(t, err)
assert.Equal(t, 1, len(policies))
rules := computeRules(policies[0])
assert.Equal(t, 3, len(rules))
}

View file

@ -1,5 +1,5 @@
package autogen
import "sigs.k8s.io/controller-runtime/pkg/log"
import "github.com/kyverno/kyverno/pkg/logging"
var logger = log.Log.WithName("autogen")
var logger = logging.WithName("autogen")

View file

@ -149,7 +149,7 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
rule.Validation = deny
return rule
}
if rule.Validation.PodSecurity != nil && len(rule.Validation.PodSecurity.Exclude) > 0 {
if rule.Validation.PodSecurity != nil {
newExclude := make([]kyvernov1.PodSecurityStandard, len(rule.Validation.PodSecurity.Exclude))
copy(newExclude, rule.Validation.PodSecurity.Exclude)
podSecurity := kyvernov1.Validation{

View file

@ -5,11 +5,12 @@ import (
"reflect"
"strings"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/logging"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
pkglabels "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
"sigs.k8s.io/controller-runtime/pkg/log"
)
type Object interface {
@ -70,12 +71,12 @@ func GenerateLabelsSet(policyKey string, trigger Object) pkglabels.Set {
func managedBy(labels map[string]string) {
// ManagedBy label
key := "app.kubernetes.io/managed-by"
value := "kyverno"
key := kyvernov1.LabelAppManagedBy
value := kyvernov1.ValueKyvernoApp
val, ok := labels[key]
if ok {
if val != value {
log.Log.V(2).Info(fmt.Sprintf("resource managed by %s, kyverno wont over-ride the label", val))
logging.V(2).Info(fmt.Sprintf("resource managed by %s, kyverno wont over-ride the label", val))
return
}
}
@ -103,7 +104,7 @@ func checkGeneratedBy(labels map[string]string, key, value string) {
val, ok := labels[key]
if ok {
if val != value {
log.Log.V(2).Info(fmt.Sprintf("kyverno wont over-ride the label %s", key))
logging.V(2).Info(fmt.Sprintf("kyverno wont over-ride the label %s", key))
return
}
}

View file

@ -9,10 +9,10 @@ import (
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/logging"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/log"
)
var DefaultRetry = wait.Backoff{
@ -27,21 +27,21 @@ func Update(client versioned.Interface, urLister kyvernov1beta1listers.UpdateReq
err := retry.RetryOnConflict(DefaultRetry, func() error {
ur, err := urLister.Get(name)
if err != nil {
log.Log.Error(err, "[ATTEMPT] failed to fetch update request", "name", name)
logging.Error(err, "[ATTEMPT] failed to fetch update request", "name", name)
return err
}
ur = ur.DeepCopy()
mutator(ur)
_, err = client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Update(context.TODO(), ur, metav1.UpdateOptions{})
if err != nil {
log.Log.Error(err, "[ATTEMPT] failed to update update request", "name", name)
logging.Error(err, "[ATTEMPT] failed to update update request", "name", name)
}
return err
})
if err != nil {
log.Log.Error(err, "failed to update update request", "name", name)
logging.Error(err, "failed to update update request", "name", name)
} else {
log.Log.V(3).Info("updated update request", "name", name, "status")
logging.V(3).Info("updated update request", "name", name, "status")
}
return ur, err
}
@ -51,7 +51,7 @@ func UpdateStatus(client versioned.Interface, urLister kyvernov1beta1listers.Upd
err := retry.RetryOnConflict(DefaultRetry, func() error {
ur, err := urLister.Get(name)
if err != nil {
log.Log.Error(err, "[ATTEMPT] failed to fetch update request", "name", name)
logging.Error(err, "[ATTEMPT] failed to fetch update request", "name", name)
return err
}
ur = ur.DeepCopy()
@ -62,15 +62,15 @@ func UpdateStatus(client versioned.Interface, urLister kyvernov1beta1listers.Upd
}
_, err = client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), ur, metav1.UpdateOptions{})
if err != nil {
log.Log.Error(err, "[ATTEMPT] failed to update update request status", "name", name)
logging.Error(err, "[ATTEMPT] failed to update update request status", "name", name)
return err
}
return err
})
if err != nil {
log.Log.Error(err, "failed to update update request status", "name", name)
logging.Error(err, "failed to update update request status", "name", name)
} else {
log.Log.V(3).Info("updated update request status", "name", name, "status", string(state))
logging.V(3).Info("updated update request status", "name", name, "status", string(state))
}
return ur, err
}

View file

@ -678,7 +678,7 @@ func manageCloneList(log logr.Logger, namespace, policy string, clone kyvernov1.
for _, kind := range kinds {
apiVersion, kind := kubeutils.GetKindFromGVK(kind)
resources, err := client.ListResource(apiVersion, kind, rNamespace, nil)
resources, err := client.ListResource(apiVersion, kind, rNamespace, clone.CloneList.Selector)
if err != nil {
response = append(response, GenerateResponse{
Data: nil,

View file

@ -8,7 +8,7 @@ import (
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/engine/common"
"github.com/kyverno/kyverno/pkg/engine/wildcards"
"sigs.k8s.io/controller-runtime/pkg/log"
"github.com/kyverno/kyverno/pkg/logging"
)
type Handler struct {
@ -147,7 +147,7 @@ func (dh Handler) Handle(handler resourceElementHandler, resourceMap map[string]
} else if dh.pattern == "*" && resourceMap[dh.element] == nil {
return dh.path, fmt.Errorf("failed at path %s, field %s is not present", dh.path, dh.element)
} else {
path, err := handler(log.Log, resourceMap[dh.element], dh.pattern, originPattern, currentPath)
path, err := handler(logging.GlobalLogger(), resourceMap[dh.element], dh.pattern, originPattern, currentPath)
if err != nil {
return path, err
}

Some files were not shown because too many files have changed in this diff Show more