Compare commits

..

No commits in common. "main" and "v0.1.9" have entirely different histories.
main ... v0.1.9

978 changed files with 27353 additions and 80975 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,36 +7,24 @@ labels: ["bug", "triage"]
body: body:
- type: markdown - type: markdown
attributes: attributes:
value: Please tell us about the bug. value: |
Please tell us about the bug.
- type: dropdown - type: dropdown
id: chainsaw-version id: chainsaw-version
attributes: attributes:
label: chainsaw version Version label: chainsaw version Version
description: What version of chainsaw are you running? description: >-
What version of the chainsaw are you running?
options: options:
- v0.2.12 - v0.1.0
- v0.2.11 - v0.1.1
- v0.2.10 - v0.1.2
- v0.2.9 - v0.1.3
- v0.2.8 - v0.1.4
- v0.2.7 - v0.1.5
- v0.2.6 - v0.1.6
- v0.2.5 - v0.1.7
- v0.2.4 - v0.1.8
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@ -2,57 +2,47 @@
name: General Question name: General Question
description: Ask a question or need support description: Ask a question or need support
title: '[Question] ' title: "[Question] "
labels: labels: ["question"]
- question
body: body:
- type: markdown - type: markdown
attributes: attributes:
value: Please answer these questions before submitting your issue. Thanks! value: "Please answer these questions before submitting your issue. Thanks!"
- type: textarea - type: textarea
id: describe-your-question id: describe-your-question
attributes: attributes:
label: Describe your question label: Describe your question
description: Provide details about your question or the support needed. description: "Provide details about your question or the support needed."
placeholder: Type your question here... placeholder: "Type your question here..."
validations: validations:
required: true required: true
- type: dropdown - type: dropdown
id: chainsaw-version id: chainsaw-version
attributes: attributes:
label: chainsaw version Version label: chainsaw version Version
description: What version of chainsaw are you running? description: >-
What version of the chainsaw are you running?
options: options:
- v0.2.12 - v0.1.0
- v0.2.11 - v0.1.1
- v0.2.10 - v0.1.2
- v0.2.9 - v0.1.3
- v0.2.8 - v0.1.4
- v0.2.7 - v0.1.5
- v0.2.6 - v0.1.6
- v0.2.5 - v0.1.7
- v0.2.4 - v0.1.8
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: additional-context id: additional-context
attributes: attributes:
label: Additional context label: Additional context
description: Add any other context or screenshots about the question here. description: "Add any other context or screenshots about the question here."
placeholder: Additional details... placeholder: "Additional details..."
validations: validations:
required: false required: false

View File

@ -1,9 +1,7 @@
version: 2 version: 2
updates: updates:
- package-ecosystem: gomod - package-ecosystem: gomod
directories: directory: /
- /
- /hack/controller-gen/
schedule: schedule:
interval: daily interval: daily
- package-ecosystem: github-actions - package-ecosystem: github-actions

View File

@ -8,24 +8,22 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- release-*
push: push:
branches: branches:
- main - main
- release-*
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
check-actions: required:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Ensure SHA pinned actions - name: Ensure SHA pinned actions
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@fc87bb5b5a97953d987372e74478de634726b3e5 # v3.0.25 uses: zgosalvez/github-actions-ensure-sha-pinned-actions@ba37328d4ea95eaf8b3bd6c6cef308f709a5f2ec # v3.0.3
with: with:
# slsa-github-generator requires using a semver tag for reusable workflows. # slsa-github-generator requires using a semver tag for reusable workflows.
# See: https://github.com/slsa-framework/slsa-github-generator#referencing-slsa-builders-and-generators # See: https://github.com/slsa-framework/slsa-github-generator#referencing-slsa-builders-and-generators

View File

@ -1,40 +0,0 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Check milestone
permissions: {}
on:
pull_request:
branches:
- main
- release-*
types:
- opened
- demilestoned
- milestoned
- edited
- synchronize
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check-milestone:
runs-on: ubuntu-latest
steps:
- name: Check milestone
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { data } = await github.request("GET /repos/{owner}/{repo}/pulls/{pr}", {
owner: context.repo.owner,
repo: context.repo.repo,
pr: context.payload.pull_request.number
});
if (data.milestone) {
core.info(`This pull request has a milestone set: ${data.milestone.title}`);
} else {
core.setFailed(`A milestone need to be set on this pull request.`);
}

View File

@ -8,24 +8,22 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- release-*
push: push:
branches: branches:
- main - main
- release-*
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
codegen-verify: required:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum

View File

@ -8,28 +8,26 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- release-*
push: push:
branches: branches:
- main - main
- release-*
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
scan-trivy: required:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
security-events: write security-events: write
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode - name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4 # v0.32.0 uses: aquasecurity/trivy-action@062f2592684a31eb3aa050cc61e7ca1451cecd3d # v0.18.0
with: with:
scan-type: fs scan-type: fs
ignore-unfixed: false ignore-unfixed: false
@ -39,10 +37,8 @@ jobs:
scanners: vuln,secret scanners: vuln,secret
exit-code: '0' exit-code: '0'
vuln-type: os,library vuln-type: os,library
env:
TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2'
- name: Upload Trivy scan results to GitHub Security tab - name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@df559355d593797519d70b90fc8edd5db049e7a2 # v3.29.5 uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
with: with:
sarif_file: trivy-results.sarif sarif_file: trivy-results.sarif
category: code category: code

View File

@ -14,15 +14,15 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
docs-main: docs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum

View File

@ -7,10 +7,10 @@ permissions: {}
on: on:
push: push:
tags: tags:
- docs-v* - 'docs-v*'
jobs: jobs:
docs-release: docs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
@ -23,9 +23,9 @@ jobs:
version_extractor_regex: '^docs-v(.*)$' version_extractor_regex: '^docs-v(.*)$'
- name: Checkout - name: Checkout
if: ${{ steps.semver.outputs.prerelease == '' }} if: ${{ steps.semver.outputs.prerelease == '' }}
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
if: ${{ steps.semver.outputs.prerelease == '' }} if: ${{ steps.semver.outputs.prerelease == '' }}
with: with:
go-version-file: go.mod go-version-file: go.mod

View File

@ -8,28 +8,26 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- release-*
push: push:
branches: branches:
- main - main
- release-*
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
golangci-lint: required:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v3.7.1
with: with:
skip-cache: true skip-cache: true

View File

@ -1,5 +1,3 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
# feat: (new feature for the user, not a new feature for build script) # feat: (new feature for the user, not a new feature for build script)
# fix: (bug fix for the user, not a fix to a build script) # fix: (bug fix for the user, not a fix to a build script)
# build: (changes that affect the build system or external dependencies) # build: (changes that affect the build system or external dependencies)
@ -20,84 +18,73 @@
# | |_______ Scope # | |_______ Scope
# |____________ Type # |____________ Type
name: Semantic pull request name: Semantic PR Validation
permissions: {}
on: on:
pull_request: pull_request_target:
branches:
- main
- release-*
types: types:
- opened - opened
- reopened - edited
- labeled - synchronize
- unlabeled defaults:
- edited run:
- synchronize shell: bash
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
check-semantic-pr: validate:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Validate Pull Request - name: Validate Pull Request
uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
# Configure which types are allowed. # Configure which types are allowed.
# Default: https://github.com/commitizen/conventional-commit-types # Default: https://github.com/commitizen/conventional-commit-types
types: | types: |
feat feat
fix fix
build build
chore chore
ci ci
docs docs
perf perf
refactor refactor
revert revert
style style
test test
revert revert
release release
# Configure which scopes are allowed. # Configure which scopes are allowed.
scopes: | scopes: |
api api
client client
commands commands
config config
data data
deps deps
discovery discovery
internal internal
report report
resource resource
runner runner
operations operations
processors processors
test test
utils utils
validation validation
version version
docs docs
release release
testdata testdata
ignoreLabels: | ignoreLabels: |
bot bot
ignore-semantic-pull-request ignore-semantic-pull-request
# Configure that a scope must always be provided. # Configure that a scope must always be provided.
requireScope: false requireScope: false
# When using "Squash and merge" on a PR with only one commit, GitHub # When using "Squash and merge" on a PR with only one commit, GitHub
# will suggest using that commit message instead of the PR title for the # will suggest using that commit message instead of the PR title for the
# merge commit, and it's easy to commit this by mistake. Enable this option # merge commit, and it's easy to commit this by mistake. Enable this option
# to also validate the commit message for one commit PRs. # to also validate the commit message for one commit PRs.
validateSingleCommit: true validateSingleCommit: true
# Related to `validateSingleCommit` you can opt-in to validate that the PR # Related to `validateSingleCommit` you can opt-in to validate that the PR
# title matches a single commit to avoid confusion. # title matches a single commit to avoid confusion.
validateSingleCommitMatchesPrTitle: true validateSingleCommitMatchesPrTitle: true

View File

@ -7,7 +7,7 @@ permissions: {}
on: on:
push: push:
tags: tags:
- v* - 'v*'
jobs: jobs:
goreleaser: goreleaser:
@ -33,7 +33,7 @@ jobs:
docker-images: true docker-images: true
swap-storage: false swap-storage: false
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Fetch all tags - name: Fetch all tags
@ -41,19 +41,19 @@ jobs:
set -e set -e
git fetch --force --tags git fetch --force --tags
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum
- name: Install Cosign - name: Install Cosign
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0
- name: Install Syft - name: Install Syft
uses: anchore/sbom-action/download-syft@7b36ad622f042cab6f59a75c2ac24ccb256e9b45 # v0.20.4 uses: anchore/sbom-action/download-syft@9fece9e20048ca9590af301449208b2b8861333b # v0.15.9
- name: Install Ko - name: Install Ko
uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6
- name: Run GoReleaser - name: Run GoReleaser
id: goreleaser id: goreleaser
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
with: with:
distribution: goreleaser distribution: goreleaser
version: latest version: latest
@ -61,14 +61,14 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifacts.json - name: Upload artifacts.json
uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # 2.11.2 uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # 2.9.0
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/artifacts.json file: dist/artifacts.json
asset_name: artifacts.json asset_name: artifacts.json
tag: ${{ github.ref }} tag: ${{ github.ref }}
- name: Upload metadata.json - name: Upload metadata.json
uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # 2.11.2 uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # 2.9.0
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/metadata.json file: dist/metadata.json
@ -102,7 +102,7 @@ jobs:
actions: read actions: read
id-token: write id-token: write
contents: write contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0
with: with:
base64-subjects: "${{ needs.goreleaser.outputs.hashes }}" base64-subjects: "${{ needs.goreleaser.outputs.hashes }}"
upload-assets: true upload-assets: true
@ -114,7 +114,7 @@ jobs:
actions: read actions: read
id-token: write id-token: write
packages: write packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
with: with:
image: ${{ needs.goreleaser.outputs.image }} image: ${{ needs.goreleaser.outputs.image }}
digest: ${{ needs.goreleaser.outputs.digest }} digest: ${{ needs.goreleaser.outputs.digest }}

View File

@ -8,11 +8,9 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- release-*
push: push:
branches: branches:
- main - main
- release-*
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
@ -23,9 +21,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum
@ -38,7 +36,7 @@ jobs:
set -e set -e
make tests make tests
- name: Upload coverage - name: Upload coverage
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with: with:
name: coverage.out name: coverage.out
path: coverage.out path: coverage.out
@ -50,12 +48,14 @@ jobs:
- unit-tests - unit-tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Download coverage - name: Download coverage
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with: with:
name: coverage.out name: coverage.out
- name: Upload Report to Codecov - name: Upload Report to Codecov
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0
with: with:
files: ./coverage.out files: ./coverage.out
fail_ci_if_error: true fail_ci_if_error: true
@ -67,9 +67,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum
@ -82,33 +82,18 @@ jobs:
set -e set -e
make e2e-tests make e2e-tests
e2e-tests-no-cluster:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- name: Run tests
run: |
set -e
make e2e-tests-no-cluster
e2e-test-ko: e2e-test-ko:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with: with:
go-version-file: go.mod go-version-file: go.mod
cache-dependency-path: go.sum cache-dependency-path: go.sum
- name: Install ko - name: Install ko
uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d #v0.9 uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa #v0.6
- name: Create test cluster - name: Create test cluster
run: | run: |
set -e set -e
@ -117,3 +102,12 @@ jobs:
run: | run: |
set -e set -e
make e2e-tests-ko make e2e-tests-ko
required:
needs:
- unit-tests
- e2e-tests
- e2e-test-ko
runs-on: ubuntu-latest
steps:
- run: echo "Required jobs success!"

2
.gitignore vendored
View File

@ -1,8 +1,6 @@
.cache/
.gopath/ .gopath/
.temp/ .temp/
.tools/ .tools/
.venv/
chainsaw chainsaw
coverage.out coverage.out
website/site website/site

View File

@ -1,4 +1,3 @@
version: "2"
linters: linters:
enable: enable:
- asasalint - asasalint
@ -6,49 +5,44 @@ linters:
- bidichk - bidichk
- bodyclose - bodyclose
- containedctx - containedctx
- copyloopvar
- decorder - decorder
- dogsled - dogsled
- durationcheck - durationcheck
- errcheck
- errname - errname
- exportloopref
- gci
- gochecknoinits - gochecknoinits
- gofmt
- gofumpt
- goimports
- goprintffuncname - goprintffuncname
- gosec - gosec
- gosimple
- govet
- grouper - grouper
- importas - importas
- ineffassign
- makezero - makezero
- misspell - misspell
- noctx - noctx
- nolintlint - nolintlint
- nosprintfhostport - nosprintfhostport
# - paralleltest
- staticcheck
- tenv
- thelper - thelper
- tparallel - tparallel
- typecheck
- unconvert - unconvert
- usetesting - unused
- wastedassign - wastedassign
- whitespace - whitespace
exclusions:
generated: lax run:
presets: timeout: 15m
- comments skip-files:
- common-false-positives - ".+\\.generated.go"
- legacy output:
- std-error-handling format: colored-line-number
paths: sort-results: true
- .+\.generated.go
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
exclusions:
generated: lax
paths:
- .+\.generated.go
- third_party$
- builtin$
- examples$

View File

@ -1,5 +1,3 @@
version: 2
before: before:
hooks: hooks:
- go mod tidy - go mod tidy
@ -17,30 +15,6 @@ builds:
- -trimpath - -trimpath
ldflags: ldflags:
- -s -w -X github.com/kyverno/chainsaw/pkg/version.BuildVersion={{ .Version }} - -s -w -X github.com/kyverno/chainsaw/pkg/version.BuildVersion={{ .Version }}
- id: s390x
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- s390x
binary: chainsaw
flags:
- -trimpath
ldflags:
- -s -w -X github.com/kyverno/chainsaw/pkg/version.BuildVersion={{ .Version }}
- id: ppc64le
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- ppc64le
binary: chainsaw
flags:
- -trimpath
ldflags:
- -s -w -X github.com/kyverno/chainsaw/pkg/version.BuildVersion={{ .Version }}
kos: kos:
- build: chainsaw - build: chainsaw
@ -108,7 +82,7 @@ sboms:
artifacts: source artifacts: source
snapshot: snapshot:
version_template: '{{ incpatch .Version }}-next' name_template: '{{ incpatch .Version }}-next'
release: release:
prerelease: auto prerelease: auto

View File

@ -19,7 +19,3 @@ Release notes for `TODO`.
## 🎸 Misc 🎸 ## 🎸 Misc 🎸
--> -->
## 💫 New features 💫
- Continue tests when an error happens when computing the test name

View File

@ -1,29 +0,0 @@
# Release notes
Release notes for `v0.2.0`.
## ‼️ Breaking changes ‼️
- Deprecated `TestStep` resource support was removed as well as the related command `chainsaw migrate tests`
## 💫 New features 💫
- Added support to wait with `jsonpath` conditions
- Introduced `v1alpha2` version for configuration, both `v1alpha1` and `v1alpha2` are supported with a conversion system
- Rewrote quick-start guide leveraging chainsaw capabilities using relevant usecases
## 🔧 Fixes 🔧
- Fixed issue with `update` operation failing because resource version not set correctly
- Fixed `wait` operation timeout passing the timeout value to the underlying `kubectl` command
- Fixed `wait` operation condition incorrectly formatted with quotes
- Fixed issue reading files from embedded file systems on Windows
- Fixed incorrect JUnit report format
## 🎸 Misc 🎸
- Switched a release branch worflow
## 📚 Docs 📚
- Added missing cluster doc

View File

@ -1,18 +0,0 @@
# Release notes
Release notes for `v0.2.1`.
## ‼️ Breaking changes ‼️
- Resource templating is now enabled by default
## 💫 New features 💫
- Added `--pause-on-failure` flag to pause when a test failure happens (to ease troubleshooting)
- Improved cleanup management logic, alternating `catch`, `finally` and `@cleanup` per step
- Added support for registering clusters dynamically, useful when a cluster is created in a test step
## 🔧 Fixes 🔧
- Fixed issue with cluster incorrectly registered
- Force background deletion propagation policy (useful when testing unmanaged `Job`)

View File

@ -1,24 +0,0 @@
# Release notes
Release notes for `v0.2.10`.
## 💫 New features 💫
- Added bindings support when referencing step templates
- Restructured the reports system
- Added reports in JSON format back
- Added new JUnit report formats with different granularity (`JUNIT-TEST`, `JUNIT-STEP`, `JUNIT-OPERATION`)
- `XML` report format should be considered deprecated and replaced with one of the `JUNIT-*` format
## 🔧 Fixes 🔧
- Fixed default report name not set correctly
- Made `template` required when referencing a step template
## 📚 Docs 📚
- Started a JMESPath function example page in the docs (only `x_k8s_get` is available at this time)
## 🎸 Misc 🎸
- Removed test `v1alpha2` API for now

View File

@ -1,17 +0,0 @@
# Release notes
Release notes for `v0.2.11`.
## 💫 New features 💫
- Added CEL support everywhere (bindings, assertion trees, projection trees, outputs...)
- Added test sharding support
## 🔧 Fixes 🔧
- Fixed exit code when failing in root test run
- Fixed `--no-cluster` flag not working
## 📚 Docs 📚
- Added most JMESPath functions docs and examples

View File

@ -1,15 +0,0 @@
# Release notes
Release notes for `v0.2.12`.
## 💫 New features 💫
- Registered Kubernetes CEL libs, optional types, and various other std libs
- Support conditions in labels in assertion templates
- Added `skipCommandOutput` support to not log the `command` and `script` being executed
## 🔧 Fixes 🔧
- Allow escaping dollar sign in `command` and `script`
- Fixed `chainsaw build docs` rendering invalid yaml
- Fixed step template bindings registered in the wrong order

View File

@ -1,25 +0,0 @@
# Release notes
Release notes for `v0.2.2`.
## ‼️ Breaking changes ‼️
- `finally` block now executes when the step terminates. It was supposed to work like this from the beginning but was not properly working. The `cleanup` block was introduced to execute operations when a test terminates instead.
## 💫 New features 💫
- Added cleanup handlers support to register custom cleanup operations to run when a test terminates
## 🔧 Fixes 🔧
- Use `namespaceTemplate` from configuration if provided
## 📚 Docs 📚
- Improved home page
- Added scroll to top button
- Improved navigation bar
- Fixed dark/light color schemes and added system preference support
- Added links to Slack and X/Twitter links in the footer
- Removed the blog
- Rewrote most of the Getting Started pages

View File

@ -1,28 +0,0 @@
# Release notes
Release notes for `v0.2.3`.
## ‼️ Breaking changes ‼️
- `catch` block in v1alpha2 configuration was moved in `error.catch`
## 💫 New features 💫
- Added `cleanup` validation logic
- Added deletion propagation policy support at the configuration, test and step levels
## 🔧 Fixes 🔧
- Added `cleanup` support to generated test catalog
## 📚 Docs 📚
- Documentation sections have been completely restructured for better clarity and maintenance
- Tons of documentation improvements
- Configuration examples in the documentation were updated to `v1alpha2`
- Added built-in bindings reference documentation
- Links to easily navigate from one section to another were added to the home page
## 🎸 Misc 🎸
- Social cards are now enabled and configured for all social networks/apps

View File

@ -1,27 +0,0 @@
# Release notes
Release notes for `v0.2.4`.
## ‼️ Breaking changes ‼️
- Directly specifying resource name was dropped, only `apiVersion` / `kind` is supported now
## 💫 New features 💫
- Added test metadata built-in binding
- Added file support to `delete` operation
- Added `--remarshal` flag to improve anchors support in test resources
- Added support for `describe`, `events`, `get` and `podLogs` operations in try blocks
## 🔧 Fixes 🔧
- Fixed incorrect path reported when validation failed for a patch operation
- Improved the way default values for configuration options are managed in configuration v1alpha2
## 📚 Docs 📚
- Removed code markers on titles in API reference documentation
## 🎸 Misc 🎸
- Bumped kyverno-json to v0.0.3

View File

@ -1,15 +0,0 @@
# Release notes
Release notes for `v0.2.5`.
## 💫 New features 💫
- Add test scenarios support
## 🔧 Fixes 🔧
- Fixed a potential issue with configuration defaults and marshaling
## 🎸 Misc 🎸
- Improved all Python-based build operations

View File

@ -1,9 +0,0 @@
# Release notes
Release notes for `v0.2.6`.
## 💫 New features 💫
- Added a `proxy` action to allow HTTP calls to in-cluster services and pods
- Added `as_string` JMESPath function to convert types based on strings to bare strings
- Added `x_metrics_decode` JMESPath function to decode Prometheus metrics

View File

@ -1,18 +0,0 @@
# Release notes
Release notes for `v0.2.7`.
## 💫 New features 💫
- Added initial `TestTemplate` support to allow defining steps in separate files and reusing them across tests
- Replaced programmatic validation with schema-based validation
- Better generated JSON schemas based on OpenAPI v3 instead of v2
## 🔧 Fixes 🔧
- Fixed incorrect `null` vs empty object comparison in assertion operations
## 📚 Docs 📚
- Added detailed community pages to the website website
- Added a CODE_OF_CONDUCT.md file in the repo

View File

@ -1,21 +0,0 @@
# Release notes
Release notes for `v0.2.8`.
## 💫 New features 💫
- Added `chainsaw renovate config` to upgrade configuration manifests to `v1alpha2`
- Changed `cluster` in test step and actions to a pointer
- `null` means inherit the current cluster
- an empty string means the default cluster
- Made default timeouts part of the schemas
- Added support to fail fast at the test level (test will be skipped if a previous error was already reported)
- Delay operation loading until operation execution
- Generate strict JSON schemas
## 🔧 Fixes 🔧
- Fixed incorrect bindings when operations are run against different clusters
- Fixed operation info built-in bindings not registered before other bindings
- Fixed incorrect cluster client used when applying the test namespace to resources
- Detect accessing nodes not present in the payload when traversing an assertion tree

View File

@ -1,19 +0,0 @@
# Release notes
Release notes for `v0.2.9`.
## 💫 New features 💫
- Added support for templating filenames used in operations
- Added `ppc64le` and `s390x` binaries in release artifacts
- Added support for Kubernetes 1.31
- Added server side validation to validate the submitted resource
- Added support for overriding the working directory in `command` and `script` operations
- Compile string expressions at loading time
- Made json path value optional in `wait` operation
- Improved logging with `begin`, `end` and `warning` statuses
- Added golang 1.23 support
## 🔧 Fixes 🔧
- Fixed configuration `v1alpha2` lint command

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
.vscode/launch.json vendored
View File

@ -16,7 +16,6 @@
"./testdata/e2e/examples", "./testdata/e2e/examples",
"--config", "--config",
"./testdata/e2e/config.yaml", "./testdata/e2e/config.yaml",
"--remarshal",
] ]
}, },
{ {

View File

@ -9,7 +9,6 @@ The list of organizations that have publicly shared the usage of Chainsaw:
| Organization | Success Story | | Organization | Success Story |
|:--|:--| |:--|:--|
| [Keptn](https://github.com/keptn/lifecycle-toolkit)| Chainsaw replaced Kuttl, and helped us get rid of many unreadable bash scripts | | [Keptn](https://github.com/keptn/lifecycle-toolkit)| Chainsaw replaced Kuttl, and helped us get rid of many unreadable bash scripts |
| [OpenFeature](https://github.com/open-feature/open-feature-operator)| Chainsaw replaced Kuttl, helped us improve logging and remove native kubectl calls |
| [Kyverno](https://kyverno.io) | Running all end to end tests for both Kyverno and the policies catalog | | [Kyverno](https://kyverno.io) | Running all end to end tests for both Kyverno and the policies catalog |
| [Nirmata](https://nirmata.com/) | Using Chainsaw extensively to test curated Kyverno policies, Kyverno Operator and other e2e internal testing | | [Nirmata](https://nirmata.com/) | Using Chainsaw extensively to test curated Kyverno policies, Kyverno Operator and other e2e internal testing |
| [Redis-operator](https://github.com/OT-CONTAINER-KIT/redis-operator) | Chainsaw helped a lot for declarative assertion of Redis Cluster state against various e2e test | | [Redis-operator](https://github.com/OT-CONTAINER-KIT/redis-operator) | Chainsaw helped a lot for declarative assertion of Redis Cluster state against various e2e test |
@ -18,11 +17,6 @@ The list of organizations that have publicly shared the usage of Chainsaw:
| [Grafana-operator](https://github.com/grafana/grafana-operator) | Chainsaw enabled easier e2e testing and CI debugging after replacing kuttl | | [Grafana-operator](https://github.com/grafana/grafana-operator) | Chainsaw enabled easier e2e testing and CI debugging after replacing kuttl |
| [Opentelemetry-operator](https://github.com/open-telemetry/opentelemetry-operator) | Chainsaw cut down on hacks, improved code-reuse and enhanced test debugging | | [Opentelemetry-operator](https://github.com/open-telemetry/opentelemetry-operator) | Chainsaw cut down on hacks, improved code-reuse and enhanced test debugging |
| [Tempo-operator](https://github.com/grafana/tempo-operator) | Chainsaw cranked up the tempo, making our e2e tests dance to a rhythm of reliability and efficiency | | [Tempo-operator](https://github.com/grafana/tempo-operator) | Chainsaw cranked up the tempo, making our e2e tests dance to a rhythm of reliability and efficiency |
| [Provider-ceph](https://github.com/linode/provider-ceph) | Chainsaw replaced Kuttl and made our e2e tests much more readable and easier to debug |
| [Linode CAPI provider](https://github.com/linode/cluster-api-provider-linode) | Chainsaw replaced Kuttl and made our e2e tests much more readable and easier to debug. 🙏 @eddycharly |
| [Linode COSI driver](https://github.com/linode/linode-cosi-driver) | Running all end to end tests for object store driver |
| [Odigos](https://github.com/odigos-io/odigos) | Chainsaw helps us run complex e2e tests confidently, ensuring project reliability. |
<!-- append the line below to the table <!-- append the line below to the table
| [name](URL) | brief description of how you are using Chainsaw | | [name](URL) | brief description of how you are using Chainsaw |

View File

@ -1,74 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for our community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team privately at hello@squidfunk.com. The
project team will review and investigate all complaints, and will respond in a
way that it deems appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an
incident. Further details of specific enforcement policies may be posted
separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

107
Makefile
View File

@ -7,6 +7,9 @@
GIT_SHA := $(shell git rev-parse HEAD) GIT_SHA := $(shell git rev-parse HEAD)
ORG ?= kyverno ORG ?= kyverno
PACKAGE ?= github.com/$(ORG)/chainsaw PACKAGE ?= github.com/$(ORG)/chainsaw
GOPATH_SHIM := ${PWD}/.gopath
PACKAGE_SHIM := $(GOPATH_SHIM)/src/$(PACKAGE)
INPUT_DIRS := $(PACKAGE)/pkg/apis/v1alpha1
CRDS_PATH := ${PWD}/.crds CRDS_PATH := ${PWD}/.crds
CLI_BIN := chainsaw CLI_BIN := chainsaw
CGO_ENABLED ?= 0 CGO_ENABLED ?= 0
@ -18,7 +21,7 @@ LD_FLAGS := "-s -w"
endif endif
KO_REGISTRY := ko.local KO_REGISTRY := ko.local
KO_TAGS := $(GIT_SHA) KO_TAGS := $(GIT_SHA)
KIND_IMAGE ?= kindest/node:v1.33.2 KIND_IMAGE ?= kindest/node:v1.29.2
######### #########
# TOOLS # # TOOLS #
@ -26,17 +29,17 @@ KIND_IMAGE ?= kindest/node:v1.33.2
TOOLS_DIR := $(PWD)/.tools TOOLS_DIR := $(PWD)/.tools
CONTROLLER_GEN := $(TOOLS_DIR)/controller-gen CONTROLLER_GEN := $(TOOLS_DIR)/controller-gen
CONTROLLER_GEN_VERSION := v0.12.0
REGISTER_GEN := $(TOOLS_DIR)/register-gen REGISTER_GEN := $(TOOLS_DIR)/register-gen
DEEPCOPY_GEN := $(TOOLS_DIR)/deepcopy-gen DEEPCOPY_GEN := $(TOOLS_DIR)/deepcopy-gen
CONVERSION_GEN := $(TOOLS_DIR)/conversion-gen CODE_GEN_VERSION := v0.28.0
CODE_GEN_VERSION := v0.33.3
REFERENCE_DOCS := $(TOOLS_DIR)/genref REFERENCE_DOCS := $(TOOLS_DIR)/genref
REFERENCE_DOCS_VERSION := latest REFERENCE_DOCS_VERSION := latest
KIND := $(TOOLS_DIR)/kind KIND := $(TOOLS_DIR)/kind
KIND_VERSION := v0.29.0 KIND_VERSION := v0.22.0
KO ?= $(TOOLS_DIR)/ko KO ?= $(TOOLS_DIR)/ko
KO_VERSION ?= v0.18.0 KO_VERSION ?= v0.15.1
TOOLS := $(CONTROLLER_GEN) $(REGISTER_GEN) $(DEEPCOPY_GEN) $(CONVERSION_GEN) $(REFERENCE_DOCS) $(KIND) $(KO) TOOLS := $(CONTROLLER_GEN) $(REGISTER_GEN) $(DEEPCOPY_GEN) $(REFERENCE_DOCS) $(KIND) $(KO)
PIP ?= "pip" PIP ?= "pip"
ifeq ($(GOOS), darwin) ifeq ($(GOOS), darwin)
SED := gsed SED := gsed
@ -47,7 +50,7 @@ COMMA := ,
$(CONTROLLER_GEN): $(CONTROLLER_GEN):
@echo Install controller-gen... >&2 @echo Install controller-gen... >&2
@cd ./hack/controller-gen && GOBIN=$(TOOLS_DIR) go install -buildvcs=false @GOBIN=$(TOOLS_DIR) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION)
$(REGISTER_GEN): $(REGISTER_GEN):
@echo Install register-gen... >&2 @echo Install register-gen... >&2
@ -57,10 +60,6 @@ $(DEEPCOPY_GEN):
@echo Install deepcopy-gen... >&2 @echo Install deepcopy-gen... >&2
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/deepcopy-gen@$(CODE_GEN_VERSION) @GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/deepcopy-gen@$(CODE_GEN_VERSION)
$(CONVERSION_GEN):
@echo Install conversion-gen... >&2
@GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/conversion-gen@$(CODE_GEN_VERSION)
$(REFERENCE_DOCS): $(REFERENCE_DOCS):
@echo Install genref... >&2 @echo Install genref... >&2
@GOBIN=$(TOOLS_DIR) go install github.com/kubernetes-sigs/reference-docs/genref@$(REFERENCE_DOCS_VERSION) @GOBIN=$(TOOLS_DIR) go install github.com/kubernetes-sigs/reference-docs/genref@$(REFERENCE_DOCS_VERSION)
@ -86,42 +85,40 @@ clean-tools: ## Remove installed tools
# CODEGEN # # CODEGEN #
########### ###########
$(GOPATH_SHIM):
@echo Create gopath shim... >&2
@mkdir -p $(GOPATH_SHIM)
.INTERMEDIATE: $(PACKAGE_SHIM)
$(PACKAGE_SHIM): $(GOPATH_SHIM)
@echo Create package shim... >&2
@mkdir -p $(GOPATH_SHIM)/src/github.com/$(ORG) && ln -s -f ${PWD} $(PACKAGE_SHIM)
.PHONY: codegen-register .PHONY: codegen-register
codegen-register: ## Generate types registrations codegen-register: ## Generate types registrations
codegen-register: $(PACKAGE_SHIM)
codegen-register: $(REGISTER_GEN) codegen-register: $(REGISTER_GEN)
@echo Generate registration... >&2 @echo Generate registration... >&2
@$(REGISTER_GEN) \ @GOPATH=$(GOPATH_SHIM) $(REGISTER_GEN) \
--go-header-file=./hack/boilerplate.go.txt \ --go-header-file=./.hack/boilerplate.go.txt \
--output-file zz_generated.register.go \ --input-dirs=$(INPUT_DIRS)
./pkg/apis/...
.PHONY: codegen-deepcopy .PHONY: codegen-deepcopy
codegen-deepcopy: ## Generate deep copy functions codegen-deepcopy: ## Generate deep copy functions
codegen-deepcopy: $(PACKAGE_SHIM)
codegen-deepcopy: $(DEEPCOPY_GEN) codegen-deepcopy: $(DEEPCOPY_GEN)
@echo Generate deep copy functions... >&2 @echo Generate deep copy functions... >&2
@$(DEEPCOPY_GEN) \ @GOPATH=$(GOPATH_SHIM) $(DEEPCOPY_GEN) \
--go-header-file=./hack/boilerplate.go.txt \ --go-header-file=./.hack/boilerplate.go.txt \
--output-file=zz_generated.deepcopy.go \ --input-dirs=$(INPUT_DIRS) \
./pkg/apis/... --output-file-base=zz_generated.deepcopy
.PHONY: codegen-conversion
codegen-conversion: ## Generate conversion functions
codegen-conversion: $(CONVERSION_GEN)
@echo Generate conversion functions... >&2
@$(CONVERSION_GEN) \
--go-header-file=./hack/boilerplate.go.txt \
--output-file=zz_generated.conversion.go \
./pkg/apis/...
.PHONY: codegen-crds .PHONY: codegen-crds
codegen-crds: ## Generate CRDs codegen-crds: ## Generate CRDs
codegen-crds: $(CONTROLLER_GEN) codegen-crds: $(CONTROLLER_GEN)
codegen-crds: codegen-deepcopy
codegen-crds: codegen-register
codegen-crds: codegen-conversion
@echo Generate crds... >&2 @echo Generate crds... >&2
@rm -rf $(CRDS_PATH) @rm -rf $(CRDS_PATH)
@$(CONTROLLER_GEN) paths=./pkg/apis/... crd:crdVersions=v1,ignoreUnexportedFields=true,generateEmbeddedObjectMeta=false output:dir=$(CRDS_PATH) @$(CONTROLLER_GEN) crd paths=./pkg/apis/... crd:crdVersions=v1 output:dir=$(CRDS_PATH)
@echo Copy generated CRDs to embed in the CLI... >&2 @echo Copy generated CRDs to embed in the CLI... >&2
@rm -rf pkg/data/crds && mkdir -p pkg/data/crds @rm -rf pkg/data/crds && mkdir -p pkg/data/crds
@cp $(CRDS_PATH)/* pkg/data/crds @cp $(CRDS_PATH)/* pkg/data/crds
@ -130,24 +127,24 @@ codegen-crds: codegen-conversion
codegen-cli-docs: ## Generate CLI docs codegen-cli-docs: ## Generate CLI docs
codegen-cli-docs: build codegen-cli-docs: build
@echo Generate cli docs... >&2 @echo Generate cli docs... >&2
@rm -rf website/docs/reference/commands && mkdir -p website/docs/reference/commands @rm -rf website/docs/commands && mkdir -p website/docs/commands
@./$(CLI_BIN) docs -o website/docs/reference/commands --autogenTag=false @rm -rf docs/user/commands && mkdir -p docs/user/commands
@./$(CLI_BIN) docs -o website/docs/commands --autogenTag=false
.PHONY: codegen-api-docs .PHONY: codegen-api-docs
codegen-api-docs: ## Generate markdown API docs codegen-api-docs: ## Generate markdown API docs
codegen-api-docs: $(REFERENCE_DOCS) codegen-api-docs: $(REFERENCE_DOCS)
codegen-api-docs: codegen-deepcopy codegen-api-docs: codegen-deepcopy
codegen-api-docs: codegen-register codegen-api-docs: codegen-register
codegen-api-docs: codegen-conversion
@echo Generate api docs... >&2 @echo Generate api docs... >&2
@rm -rf ./website/docs/reference/apis @rm -rf ./website/docs/apis
@cd ./website/apis && $(REFERENCE_DOCS) -c config.yaml -f markdown -o ../docs/reference/apis @cd ./website/apis && $(REFERENCE_DOCS) -c config.yaml -f markdown -o ../docs/apis
.PHONY: codegen-jp-docs .PHONY: codegen-jp-docs
codegen-jp-docs: ## Generate JP docs codegen-jp-docs: ## Generate JP docs
@echo Generate jp docs... >&2 @echo Generate jp docs... >&2
@mkdir -p ./website/docs/reference/jp @rm -rf ./website/docs/jp && mkdir -p ./website/docs/jp
@go run ./website/jp/main.go > ./website/docs/reference/jp/functions.md @go run ./website/jp/main.go > ./website/docs/jp/functions.md
.PHONY: codegen-mkdocs .PHONY: codegen-mkdocs
codegen-mkdocs: ## Generate mkdocs website codegen-mkdocs: ## Generate mkdocs website
@ -155,7 +152,9 @@ codegen-mkdocs: codegen-cli-docs
codegen-mkdocs: codegen-api-docs codegen-mkdocs: codegen-api-docs
codegen-mkdocs: codegen-jp-docs codegen-mkdocs: codegen-jp-docs
@echo Generate mkdocs website... >&2 @echo Generate mkdocs website... >&2
@$(PIP) install -r requirements.txt @$(PIP) install mkdocs
@$(PIP) install --upgrade pip
@$(PIP) install -U mkdocs-material mkdocs-redirects mkdocs-minify-plugin mkdocs-include-markdown-plugin lunr mkdocs-rss-plugin mike
@mkdocs build -f ./website/mkdocs.yaml @mkdocs build -f ./website/mkdocs.yaml
.PHONY: codegen-schemas-openapi .PHONY: codegen-schemas-openapi
@ -172,7 +171,6 @@ codegen-schemas-openapi: $(KIND)
@sleep 15 @sleep 15
@kubectl get --raw /openapi/v2 > ./.temp/.schemas/openapi/v2/schema.json @kubectl get --raw /openapi/v2 > ./.temp/.schemas/openapi/v2/schema.json
@kubectl get --raw /openapi/v3/apis/chainsaw.kyverno.io/v1alpha1 > ./.temp/.schemas/openapi/v3/apis/chainsaw.kyverno.io/v1alpha1.json @kubectl get --raw /openapi/v3/apis/chainsaw.kyverno.io/v1alpha1 > ./.temp/.schemas/openapi/v3/apis/chainsaw.kyverno.io/v1alpha1.json
@kubectl get --raw /openapi/v3/apis/chainsaw.kyverno.io/v1alpha2 > ./.temp/.schemas/openapi/v3/apis/chainsaw.kyverno.io/v1alpha2.json
@$(KIND) delete cluster --name schema @$(KIND) delete cluster --name schema
@kubectl config use-context $(CURRENT_CONTEXT) || true @kubectl config use-context $(CURRENT_CONTEXT) || true
@ -180,15 +178,13 @@ codegen-schemas-openapi: $(KIND)
codegen-schemas-json: ## Generate json schemas codegen-schemas-json: ## Generate json schemas
codegen-schemas-json: codegen-schemas-openapi codegen-schemas-json: codegen-schemas-openapi
@echo Generate json schema... >&2 @echo Generate json schema... >&2
@$(PIP) install -r requirements.txt @$(PIP) install openapi2jsonschema --no-build-isolation
@rm -rf ./.temp/.schemas/json @rm -rf ./.temp/.schemas/json
@rm -rf ./.schemas/json @rm -rf ./.schemas/json
@openapi2jsonschema .temp/.schemas/openapi/v3/apis/chainsaw.kyverno.io/v1alpha1.json --kubernetes --strict --stand-alone --expanded -o ./.temp/.schemas/json @openapi2jsonschema ./.temp/.schemas/openapi/v2/schema.json --kubernetes --stand-alone --expanded -o ./.temp/.schemas/json
@openapi2jsonschema .temp/.schemas/openapi/v3/apis/chainsaw.kyverno.io/v1alpha2.json --kubernetes --strict --stand-alone --expanded -o ./.temp/.schemas/json
@mkdir -p ./.schemas/json @mkdir -p ./.schemas/json
@cp ./.temp/.schemas/json/configuration-chainsaw-*.json ./.schemas/json
@cp ./.temp/.schemas/json/steptemplate-chainsaw-*.json ./.schemas/json
@cp ./.temp/.schemas/json/test-chainsaw-*.json ./.schemas/json @cp ./.temp/.schemas/json/test-chainsaw-*.json ./.schemas/json
@cp ./.temp/.schemas/json/configuration-chainsaw-*.json ./.schemas/json
@echo Copy generated schemas to embed in the CLI... >&2 @echo Copy generated schemas to embed in the CLI... >&2
@rm -rf pkg/data/schemas/json && mkdir -p pkg/data/schemas/json @rm -rf pkg/data/schemas/json && mkdir -p pkg/data/schemas/json
@cp ./.schemas/json/* pkg/data/schemas/json @cp ./.schemas/json/* pkg/data/schemas/json
@ -209,7 +205,6 @@ codegen: codegen-mkdocs
codegen: codegen-register codegen: codegen-register
codegen: codegen-schemas-json codegen: codegen-schemas-json
codegen: codegen-tests-catalog codegen: codegen-tests-catalog
codegen: codegen-conversion
.PHONY: verify-codegen .PHONY: verify-codegen
verify-codegen: ## Verify all generated code and docs are up to date verify-codegen: ## Verify all generated code and docs are up to date
@ -226,8 +221,10 @@ verify-codegen: codegen
.PHONY: mkdocs-serve .PHONY: mkdocs-serve
mkdocs-serve: ## Generate and serve mkdocs website mkdocs-serve: ## Generate and serve mkdocs website
@echo Generate and serve mkdocs website... >&2 @echo Generate and servemkdocs website... >&2
@$(PIP) install -r requirements.txt @$(PIP) install mkdocs
@$(PIP) install --upgrade pip
@$(PIP) install -U mkdocs-material mkdocs-redirects mkdocs-minify-plugin mkdocs-include-markdown-plugin lunr mkdocs-rss-plugin mike
@mkdocs serve -f ./website/mkdocs.yaml @mkdocs serve -f ./website/mkdocs.yaml
######### #########
@ -283,14 +280,7 @@ tests: $(CLI_BIN)
e2e-tests: ## Run e2e tests e2e-tests: ## Run e2e tests
e2e-tests: $(CLI_BIN) e2e-tests: $(CLI_BIN)
@echo Running e2e tests... >&2 @echo Running e2e tests... >&2
@./$(CLI_BIN) test ./testdata/e2e --remarshal --config ./testdata/e2e/config.yaml --values ./testdata/e2e/values.yaml @./$(CLI_BIN) test --test-dir ./testdata/e2e --config ./testdata/e2e/config.yaml --values ./testdata/e2e/values.yaml
.PHONY: e2e-tests-no-cluster
e2e-tests-no-cluster: ## Run e2e tests with --no-cluster
e2e-tests-no-cluster: $(CLI_BIN)
@echo Running e2e tests with --no-cluster... >&2
@./$(CLI_BIN) test testdata/e2e/examples/script-env --no-cluster --remarshal --config ./testdata/e2e/config.yaml --values ./testdata/e2e/values.yaml
@./$(CLI_BIN) test testdata/e2e/examples/dynamic-clusters --no-cluster --remarshal --config ./testdata/e2e/config.yaml --values ./testdata/e2e/values.yaml
.PHONY: e2e-tests-ko .PHONY: e2e-tests-ko
e2e-tests-ko: ## Run e2e tests from a docker container e2e-tests-ko: ## Run e2e tests from a docker container
@ -304,7 +294,8 @@ e2e-tests-ko: build-ko
--user $(id -u):$(id -g) \ --user $(id -u):$(id -g) \
--name chainsaw \ --name chainsaw \
--rm \ --rm \
ko.local/github.com/kyverno/chainsaw:$(KO_TAGS) test /chainsaw --remarshal --config /chainsaw/config.yaml --values /chainsaw/values.yaml --selector !no-ko-test ko.local/github.com/kyverno/chainsaw:$(KO_TAGS) \
test /chainsaw --config /chainsaw/config.yaml --values /chainsaw/values.yaml
######## ########
# KIND # # KIND #

View File

@ -35,11 +35,10 @@ Built under the Kyverno umbrella, you can use the Kyverno Chainsaw **Slack chann
- [Nirmata Office Hours for Kyverno- Episode 9- Demonstrate Kyverno Chainsaw](https://www.youtube.com/watch?v=IrIteTTjlbU) - [Nirmata Office Hours for Kyverno- Episode 9- Demonstrate Kyverno Chainsaw](https://www.youtube.com/watch?v=IrIteTTjlbU)
- [Kubebuilder Community Meeting - February 1, 2024](https://www.youtube.com/watch?v=Ejof-wtAdQM) - [Kubebuilder Community Meeting - February 1, 2024](https://www.youtube.com/watch?v=Ejof-wtAdQM)
- [Kyverno Chainsaw 0.1.4 - Awesome new features!](https://kyverno.io/blog/2024/02/15/kyverno-chainsaw-0.1.4-awesome-new-features/) - [Kyverno Chainsaw 0.1.4 - Awesome new features!](https://kyverno.io/blog/2024/02/15/kyverno-chainsaw-0.1.4-awesome-new-features/)
- [Mastering Kubernetes Testing with Kyverno Chainsaw!](https://youtu.be/hQJWGzogIiI)
## Getting Started ## Getting Started
Please refer to the [Getting Started](https://kyverno.github.io/chainsaw/latest/quick-start/) documentation. Please refer to the [Getting Started](https://kyverno.github.io/chainsaw/latest/intro/) documentation.
## RoadMap ## RoadMap
@ -51,7 +50,7 @@ To attend our community meetings, join the [Chainsaw group](https://groups.googl
You will then be sent a meeting invite and will have access to the agenda and meeting notes. You will then be sent a meeting invite and will have access to the agenda and meeting notes.
Any member may suggest topics for discussion. Any member may suggest topics for discussion.
This is a public, weekly meeting for Kyverno-Chainsaw maintainers to make announcements and provide project updates, and request input and feedback. This is a public, weekly for Kyverno-Chainsaw maintainers to make announcements and provide project updates, and request input and feedback.
This forum allows community members to raise agenda items of any sort, including but not limited to any PRs or issues on which they are working. This forum allows community members to raise agenda items of any sort, including but not limited to any PRs or issues on which they are working.
Weekly every Thursday at 2:00 PM UTC Weekly every Thursday at 2:00 PM UTC

View File

@ -5,20 +5,20 @@
class Chainsaw < Formula class Chainsaw < Formula
desc "Declarative Kubernetes end-to-end testing." desc "Declarative Kubernetes end-to-end testing."
homepage "https://kyverno.github.io/chainsaw" homepage "https://kyverno.github.io/chainsaw"
version "0.2.12" version "0.1.8"
on_macos do on_macos do
on_intel do if Hardware::CPU.arm?
url "https://github.com/kyverno/chainsaw/releases/download/v0.2.12/chainsaw_darwin_amd64.tar.gz" url "https://github.com/kyverno/chainsaw/releases/download/v0.1.8/chainsaw_darwin_arm64.tar.gz"
sha256 "b49dba1214b32024567b1edc7653498a644fbef18111bcc3e1c46dc52e1d194e" sha256 "41f1d7992ef266a95273e371e98c2bc835c0c310d2b299b0f44852c64ad0569c"
def install def install
bin.install "chainsaw" bin.install "chainsaw"
end end
end end
on_arm do if Hardware::CPU.intel?
url "https://github.com/kyverno/chainsaw/releases/download/v0.2.12/chainsaw_darwin_arm64.tar.gz" url "https://github.com/kyverno/chainsaw/releases/download/v0.1.8/chainsaw_darwin_amd64.tar.gz"
sha256 "717a07fcc4d781fff967b287880fed1d8b1e6af9fbecc7650a714c467f296d33" sha256 "df46ae522dcb6e9f9d13530e19b808a9d3f293dc22018b918ab26dc40545f184"
def install def install
bin.install "chainsaw" bin.install "chainsaw"
@ -27,24 +27,20 @@ class Chainsaw < Formula
end end
on_linux do on_linux do
on_intel do if Hardware::CPU.arm? && Hardware::CPU.is_64_bit?
if Hardware::CPU.is_64_bit? url "https://github.com/kyverno/chainsaw/releases/download/v0.1.8/chainsaw_linux_arm64.tar.gz"
url "https://github.com/kyverno/chainsaw/releases/download/v0.2.12/chainsaw_linux_amd64.tar.gz" sha256 "476af662222e4842f08fb21055b2260a5fed3c2e3ccc1ce3fd6eba51cae64254"
sha256 "d6bfb17ba47af2db85edc0365288f92b5e1a4566f7ff130ec9b326f96856e209"
def install def install
bin.install "chainsaw" bin.install "chainsaw"
end
end end
end end
on_arm do if Hardware::CPU.intel?
if Hardware::CPU.is_64_bit? url "https://github.com/kyverno/chainsaw/releases/download/v0.1.8/chainsaw_linux_amd64.tar.gz"
url "https://github.com/kyverno/chainsaw/releases/download/v0.2.12/chainsaw_linux_arm64.tar.gz" sha256 "f720cc50dc53b6cedf17a9630dbc12737d5ac69a9dccd6623b5d8ea2f2b210fc"
sha256 "72a6273d6da16a04e29e0fae232631b084852d21ddf25f88ed3d3de480125d30"
def install def install
bin.install "chainsaw" bin.install "chainsaw"
end
end end
end end
end end

View File

@ -1,6 +1,5 @@
ignore: ignore:
- 'hack/**/*.go' - ^pkg/apis/v1alpha1/zz_generated\.deepcopy\.go$
- 'website/**/*.go' - ^pkg/apis/v1alpha1/zz_generated\.register\.go$
- 'pkg/apis/**/zz_*.go' - ^pkg/testing/.*\.go$
- 'pkg/testing/*.go' - ^.*_test\.go$
- '**/*_test.go'

210
go.mod
View File

@ -1,105 +1,92 @@
module github.com/kyverno/chainsaw module github.com/kyverno/chainsaw
go 1.24.2 go 1.21.4
require ( require (
github.com/Masterminds/sprig v2.22.0+incompatible github.com/Masterminds/sprig v2.22.0+incompatible
github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0 github.com/dustinkirkland/golang-petname v0.0.0-20231002161417-6a283f1aaaf2
github.com/evanphx/json-patch v5.9.11+incompatible github.com/fatih/color v1.16.0
github.com/fatih/color v1.18.0 github.com/go-logr/logr v1.4.1
github.com/go-logr/logr v1.4.3
github.com/google/cel-go v0.23.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/hashicorp/go-getter v1.7.8 github.com/hashicorp/go-getter v1.7.3
github.com/jmespath-community/go-jmespath v1.1.2-0.20240930152130-6eb5a346873f github.com/jmespath-community/go-jmespath v1.1.2-0.20240117150817-e430401a2172
github.com/jstemmer/go-junit-report/v2 v2.1.0 github.com/kudobuilder/kuttl v0.15.0
github.com/kudobuilder/kuttl v0.20.0 github.com/kyverno/kyverno v1.5.0-rc1.0.20240202083228-5f0d53fe3482
github.com/kyverno/kyverno-json v0.0.4-0.20241008103124-b294ee72a2bf github.com/kyverno/kyverno-json v0.0.3-0.20240220200359-acadce6af3e8
github.com/kyverno/pkg/ext v0.0.0-20240418121121-df8add26c55c
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
github.com/prometheus/common v0.65.0 github.com/spf13/cobra v1.8.0
github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.5
github.com/spf13/pflag v1.0.7 github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/xeipuuv/gojsonschema v1.2.0 github.com/xeipuuv/gojsonschema v1.2.0
go.uber.org/multierr v1.11.0 go.uber.org/multierr v1.11.0
gopkg.in/yaml.v3 v3.0.1 golang.org/x/exp v0.0.0-20240213143201-ec583247a57a
k8s.io/api v0.33.3 k8s.io/api v0.29.2
k8s.io/apimachinery v0.33.3 k8s.io/apimachinery v0.29.2
k8s.io/apiserver v0.33.3 k8s.io/client-go v0.29.2
k8s.io/client-go v0.33.3 k8s.io/utils v0.0.0-20240102154912-e7106e64919e
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/controller-runtime v0.17.2
sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/kubectl-validate v0.0.2-0.20240102223437-fe143bcde89f
sigs.k8s.io/kubectl-validate v0.0.5-0.20241223122011-eb064d2f92d5 sigs.k8s.io/yaml v1.4.0
sigs.k8s.io/yaml v1.6.0
) )
require ( require (
cel.dev/expr v0.19.1 // indirect cloud.google.com/go v0.112.0 // indirect
cloud.google.com/go v0.115.1 // indirect cloud.google.com/go/compute v1.24.0 // indirect
cloud.google.com/go/auth v0.9.7 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect cloud.google.com/go/iam v1.1.6 // indirect
cloud.google.com/go/compute/metadata v0.5.2 // indirect cloud.google.com/go/storage v1.38.0 // indirect
cloud.google.com/go/iam v1.2.1 // indirect
cloud.google.com/go/monitoring v1.21.1 // indirect
cloud.google.com/go/storage v1.44.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.1 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect
github.com/IGLOU-EU/go-wildcard v1.0.3 // indirect github.com/IGLOU-EU/go-wildcard v1.0.3 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
github.com/aquilax/truncate v1.0.1 // indirect github.com/aquilax/truncate v1.0.0 // indirect
github.com/aws/aws-sdk-go v1.55.6 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go v1.50.20 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/blang/semver/v4 v4.0.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect
github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/emicklei/go-restful/v3 v3.11.2 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.3 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/swag v0.22.9 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.3 // indirect github.com/google/cel-go v0.17.7 // indirect
github.com/google/gnostic-models v0.6.9 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/s2a-go v0.1.8 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.13.0 // indirect github.com/googleapis/gax-go/v2 v2.12.1 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/huandu/xstrings v1.5.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/compress v1.17.6 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
@ -111,59 +98,54 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.47.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/procfs v0.12.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect github.com/ulikunitz/xz v0.5.11 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea // indirect github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea // indirect
go.etcd.io/etcd/api/v3 v3.5.21 // indirect go.etcd.io/etcd/api/v3 v3.5.11 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.21 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.11 // indirect
go.etcd.io/etcd/client/v3 v3.5.21 // indirect go.etcd.io/etcd/client/v3 v3.5.11 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect go.opentelemetry.io/otel v1.23.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.1 // indirect
go.opentelemetry.io/otel v1.33.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.23.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect go.opentelemetry.io/otel/metric v1.23.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect go.opentelemetry.io/otel/sdk v1.23.1 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect go.opentelemetry.io/otel/trace v1.23.1 // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect go.uber.org/zap v1.26.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect golang.org/x/crypto v0.19.0 // indirect
go.opentelemetry.io/proto/otlp v1.4.0 // indirect golang.org/x/net v0.21.0 // indirect
go.uber.org/zap v1.27.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/sync v0.6.0 // indirect
golang.org/x/crypto v0.38.0 // indirect golang.org/x/sys v0.17.0 // indirect
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect golang.org/x/term v0.17.0 // indirect
golang.org/x/net v0.40.0 // indirect golang.org/x/text v0.14.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/sync v0.14.0 // indirect google.golang.org/api v0.165.0 // indirect
golang.org/x/sys v0.33.0 // indirect google.golang.org/appengine v1.6.8 // indirect
golang.org/x/term v0.32.0 // indirect google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
golang.org/x/text v0.25.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9 // indirect
golang.org/x/time v0.11.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 // indirect
google.golang.org/api v0.199.0 // indirect google.golang.org/grpc v1.61.1 // indirect
google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 // indirect google.golang.org/protobuf v1.32.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/grpc/stats/opentelemetry v0.0.0-20240907200651-3ffb98b2c93a // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/apiextensions-apiserver v0.33.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/component-base v0.33.3 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect k8s.io/apiextensions-apiserver v0.29.2 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect k8s.io/apiserver v0.29.2 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect k8s.io/component-base v0.29.2 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect k8s.io/klog/v2 v2.120.1 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect k8s.io/kube-openapi v0.0.0-20240209001042-7a0d5b415232 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
) )

1209
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +0,0 @@
module github.com/kyverno/chainsaw/hack/controller-gen
go 1.24.0
require (
github.com/spf13/cobra v1.9.1
k8s.io/apiextensions-apiserver v0.33.3
sigs.k8s.io/controller-tools v0.17.2
)
require (
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gobuffalo/flect v1.0.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.31.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/apimachinery v0.33.3 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -1,135 +0,0 @@
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4=
github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-tools v0.17.2 h1:jNFOKps8WnaRKZU2R+4vRCHnXyJanVmXBWqkuUPFyFg=
sigs.k8s.io/controller-tools v0.17.2/go.mod h1:4q5tZG2JniS5M5bkiXY2/potOiXyhoZVw/U48vLkXk0=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -1,116 +0,0 @@
package main
import (
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/controller-tools/pkg/crd"
"sigs.k8s.io/controller-tools/pkg/genall"
"sigs.k8s.io/controller-tools/pkg/markers"
)
var (
allGenerators = map[string]genall.Generator{
"crd": crd.Generator{},
}
allOutputRules = map[string]genall.OutputRule{
"dir": genall.OutputToDirectory(""),
"none": genall.OutputToNothing,
"stdout": genall.OutputToStdout,
"artifacts": genall.OutputArtifacts{},
}
optionsRegistry = &markers.Registry{}
)
func init() { //nolint:gochecknoinits
for genName, gen := range allGenerators {
// make the generator options marker itself
defn := markers.Must(markers.MakeDefinition(genName, markers.DescribesPackage, gen))
if err := optionsRegistry.Register(defn); err != nil {
panic(err)
}
if helpGiver, hasHelp := gen.(genall.HasHelp); hasHelp {
if help := helpGiver.Help(); help != nil {
optionsRegistry.AddHelp(defn, help)
}
}
// make per-generation output rule markers
for ruleName, rule := range allOutputRules {
ruleMarker := markers.Must(markers.MakeDefinition(fmt.Sprintf("output:%s:%s", genName, ruleName), markers.DescribesPackage, rule))
if err := optionsRegistry.Register(ruleMarker); err != nil {
panic(err)
}
if helpGiver, hasHelp := rule.(genall.HasHelp); hasHelp {
if help := helpGiver.Help(); help != nil {
optionsRegistry.AddHelp(ruleMarker, help)
}
}
}
}
// make "default output" output rule markers
for ruleName, rule := range allOutputRules {
ruleMarker := markers.Must(markers.MakeDefinition("output:"+ruleName, markers.DescribesPackage, rule))
if err := optionsRegistry.Register(ruleMarker); err != nil {
panic(err)
}
if helpGiver, hasHelp := rule.(genall.HasHelp); hasHelp {
if help := helpGiver.Help(); help != nil {
optionsRegistry.AddHelp(ruleMarker, help)
}
}
}
// add in the common options markers
if err := genall.RegisterOptionsMarkers(optionsRegistry); err != nil {
panic(err)
}
}
type noUsageError struct{ error }
func main() {
cmd := &cobra.Command{
Use: "controller-gen",
RunE: func(c *cobra.Command, rawOpts []string) error {
oneOf, err := markers.MakeAnyTypeDefinition("kubebuilder:oneOf", markers.DescribesType, OneOf{})
if err != nil {
return err
}
not, err := markers.MakeAnyTypeDefinition("kubebuilder:not", markers.DescribesType, Not{})
if err != nil {
return err
}
// otherwise, set up the runtime for actually running the generators
rt, err := genall.FromOptions(optionsRegistry, rawOpts)
if err != nil {
return err
}
if err := rt.Collector.Registry.Register(oneOf); err != nil {
return err
}
if err := rt.Collector.Registry.Register(not); err != nil {
return err
}
if len(rt.Generators) == 0 {
return fmt.Errorf("no generators specified")
}
if hadErrs := rt.Run(); hadErrs {
// don't obscure the actual error with a bunch of usage
return noUsageError{fmt.Errorf("not all generators ran successfully")}
}
return nil
},
SilenceUsage: true, // silence the usage, then print it out ourselves if it wasn't suppressed
}
if err := cmd.Execute(); err != nil {
if _, noUsage := err.(noUsageError); !noUsage {
// print the usage unless we suppressed it
if err := cmd.Usage(); err != nil {
panic(err)
}
}
fmt.Fprintf(cmd.OutOrStderr(), "run `%[1]s %[2]s -w` to see all available markers, or `%[1]s %[2]s -h` for usage\n", cmd.CalledAs(), strings.Join(os.Args[1:], " "))
os.Exit(1)
}
}

View File

@ -1,37 +0,0 @@
package main
import (
"encoding/json"
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)
type OneOf struct {
Value any
}
func (m OneOf) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
var props apiext.JSONSchemaProps
if data, err := json.Marshal(m.Value); err != nil {
return err
} else if err := json.Unmarshal(data, &props); err != nil {
return err
}
schema.OneOf = append(schema.OneOf, props)
return nil
}
type Not struct {
Value any
}
func (m Not) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
var props apiext.JSONSchemaProps
if data, err := json.Marshal(m.Value); err != nil {
return err
} else if err := json.Unmarshal(data, &props); err != nil {
return err
}
schema.Not = &props
return nil
}

View File

@ -1,45 +0,0 @@
package apis
import (
"sync"
gocel "github.com/google/cel-go/cel"
"github.com/jmespath-community/go-jmespath/pkg/binding"
"github.com/kyverno/chainsaw/pkg/engine/functions"
"github.com/kyverno/kyverno-json/pkg/core/compilers"
"github.com/kyverno/kyverno-json/pkg/core/compilers/cel"
"github.com/kyverno/kyverno-json/pkg/core/compilers/jp"
"k8s.io/apiserver/pkg/cel/library"
)
var (
env = sync.OnceValues(func() (*gocel.Env, error) {
env, err := cel.DefaultEnv()
if err != nil {
return nil, err
}
return env.Extend(
library.URLs(),
library.Regex(),
library.Lists(),
library.Authz(),
library.Quantity(),
library.IP(),
library.CIDR(),
library.Format(),
library.AuthzSelectors(),
)
})
defaultCompilers = compilers.Compilers{
Jp: jp.NewCompiler(jp.WithFunctionCaller(functions.Caller())),
Cel: cel.NewCompiler(env),
}
DefaultCompilers = defaultCompilers.WithDefaultCompiler(compilers.CompilerJP)
)
type Bindings = binding.Bindings
var (
NewBinding = binding.NewBinding
NewBindings = binding.NewBindings
)

View File

@ -1,103 +0,0 @@
package conversion
import (
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha2"
"k8s.io/apimachinery/pkg/conversion"
)
func Convert_v1alpha2_ConfigurationSpec_To_v1alpha1_ConfigurationSpec(in *v1alpha2.ConfigurationSpec, out *v1alpha1.ConfigurationSpec, _ conversion.Scope) error {
out.SkipDelete = in.Cleanup.SkipDelete
out.DelayBeforeCleanup = in.Cleanup.DelayBeforeCleanup
out.Clusters = in.Clusters
out.DeletionPropagationPolicy = in.Deletion.Propagation
out.ExcludeTestRegex = in.Discovery.ExcludeTestRegex
out.IncludeTestRegex = in.Discovery.IncludeTestRegex
out.TestFile = in.Discovery.TestFile
out.FullName = in.Discovery.FullName
out.Catch = in.Error.Catch
out.FailFast = in.Execution.FailFast
out.Parallel = in.Execution.Parallel
out.RepeatCount = in.Execution.RepeatCount
out.ForceTerminationGracePeriod = in.Execution.ForceTerminationGracePeriod
out.Namespace = in.Namespace.Name
out.NamespaceTemplate = in.Namespace.Template
out.NamespaceTemplateCompiler = in.Namespace.Compiler
if in := in.Report; in != nil {
out.ReportFormat = v1alpha1.ReportFormatType(in.Format)
out.ReportPath = in.Path
out.ReportName = in.Name
}
out.Template = in.Templating.Enabled
out.Compiler = in.Templating.Compiler
out.Timeouts = in.Timeouts
return nil
}
func Convert_v1alpha1_ConfigurationSpec_To_v1alpha2_ConfigurationSpec(in *v1alpha1.ConfigurationSpec, out *v1alpha2.ConfigurationSpec, _ conversion.Scope) error {
out.Cleanup = v1alpha2.CleanupOptions{
SkipDelete: in.SkipDelete,
DelayBeforeCleanup: in.DelayBeforeCleanup,
}
out.Clusters = in.Clusters
out.Deletion = v1alpha2.DeletionOptions{
Propagation: in.DeletionPropagationPolicy,
}
out.Discovery = v1alpha2.DiscoveryOptions{
ExcludeTestRegex: in.ExcludeTestRegex,
IncludeTestRegex: in.IncludeTestRegex,
TestFile: in.TestFile,
FullName: in.FullName,
}
out.Error = v1alpha2.ErrorOptions{
Catch: in.Catch,
}
out.Execution = v1alpha2.ExecutionOptions{
FailFast: in.FailFast,
Parallel: in.Parallel,
RepeatCount: in.RepeatCount,
ForceTerminationGracePeriod: in.ForceTerminationGracePeriod,
}
out.Namespace = v1alpha2.NamespaceOptions{
Name: in.Namespace,
Compiler: in.NamespaceTemplateCompiler,
Template: in.NamespaceTemplate,
}
out.Report = &v1alpha2.ReportOptions{
Format: v1alpha2.ReportFormatType(in.ReportFormat),
Path: in.ReportPath,
Name: in.ReportName,
}
out.Templating = v1alpha2.TemplatingOptions{
Enabled: in.Template,
Compiler: in.Compiler,
}
out.Timeouts = in.Timeouts
return nil
}
func autoConvert_v1alpha2_Configuration_To_v1alpha1_Configuration(in *v1alpha2.Configuration, out *v1alpha1.Configuration, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1alpha2_ConfigurationSpec_To_v1alpha1_ConfigurationSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
return nil
}
// Convert_v1alpha2_Configuration_To_v1alpha1_Configuration is an autogenerated conversion function.
func Convert_v1alpha2_Configuration_To_v1alpha1_Configuration(in *v1alpha2.Configuration, out *v1alpha1.Configuration, s conversion.Scope) error {
return autoConvert_v1alpha2_Configuration_To_v1alpha1_Configuration(in, out, s)
}
func autoConvert_v1alpha1_Configuration_To_v1alpha2_Configuration(in *v1alpha1.Configuration, out *v1alpha2.Configuration, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1alpha1_ConfigurationSpec_To_v1alpha2_ConfigurationSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
return nil
}
// Convert_v1alpha1_Configuration_To_v1alpha2_Configuration is an autogenerated conversion function.
func Convert_v1alpha1_Configuration_To_v1alpha2_Configuration(in *v1alpha1.Configuration, out *v1alpha2.Configuration, s conversion.Scope) error {
return autoConvert_v1alpha1_Configuration_To_v1alpha2_Configuration(in, out, s)
}

View File

@ -1,22 +0,0 @@
package conversion
import (
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha2"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
)
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddGeneratedConversionFunc((*v1alpha2.Configuration)(nil), (*v1alpha1.Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_Configuration_To_v1alpha1_Configuration(a.(*v1alpha2.Configuration), b.(*v1alpha1.Configuration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1alpha1.Configuration)(nil), (*v1alpha2.Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_Configuration_To_v1alpha2_Configuration(a.(*v1alpha1.Configuration), b.(*v1alpha2.Configuration), scope)
}); err != nil {
return err
}
return nil
}

View File

@ -1,394 +0,0 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// ActionBindings contains bindings options for an action.
type ActionBindings struct {
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
}
// ActionCheck contains check for an action.
type ActionCheck struct {
// Check is an assertion tree to validate the operation outcome.
// +optional
Check *Check `json:"check,omitempty"`
}
// ActionCheckRef contains check reference options for an action.
// +kubebuilder:not:={required:{file,resource}}
type ActionCheckRef struct {
FileRef `json:",inline"`
// Check provides a check used in assertions.
// +optional
Check *Projection `json:"resource,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
}
// ActionClusters contains clusters options for an action.
type ActionClusters struct {
// Cluster defines the target cluster (will be inherited if not specified).
// +optional
Cluster *string `json:"cluster,omitempty"`
// Clusters holds a registry to clusters to support multi-cluster tests.
// +optional
Clusters Clusters `json:"clusters,omitempty"`
}
// ActionDryRun contains dry run options for an action.
type ActionDryRun struct {
// DryRun determines whether the file should be applied in dry run mode.
// +optional
DryRun *bool `json:"dryRun,omitempty"`
}
// ActionEnv contains environment options for an action.
type ActionEnv struct {
// Env defines additional environment variables.
// +optional
Env []Binding `json:"env,omitempty"`
// SkipLogOutput removes the output from the command. Useful for sensitive logs or to reduce noise.
// +optional
SkipLogOutput bool `json:"skipLogOutput,omitempty"`
// SkipCommandOutput removes the command from the output logs.
// +optional
SkipCommandOutput bool `json:"skipCommandOutput,omitempty"`
}
// ActionExpectations contains expectations for an action.
type ActionExpectations struct {
// Expect defines a list of matched checks to validate the operation outcome.
// +optional
Expect []Expectation `json:"expect,omitempty"`
}
// ActionFormat contains format for an action.
type ActionFormat struct {
// Format determines the output format (json or yaml).
// +optional
Format Format `json:"format,omitempty"`
}
type ActionInlineResource struct {
// Resource provides a resource to be applied.
// +kubebuilder:validation:XEmbeddedResource
// +kubebuilder:pruning:PreserveUnknownFields
// +optional
Resource *unstructured.Unstructured `json:"resource,omitempty"`
}
// ActionObject contains object selector options for an action.
type ActionObject struct {
ObjectType `json:",inline"`
ActionObjectSelector `json:",inline"`
}
// ActionObjectSelector contains object selector options for an action.
// +kubebuilder:not:={required:{name,selector}}
type ActionObjectSelector struct {
ObjectName `json:",inline"`
// Selector defines labels selector.
// +optional
Selector Expression `json:"selector,omitempty"`
}
// ActionOutputs contains outputs options for an action.
type ActionOutputs struct {
// Outputs defines output bindings.
// +optional
Outputs []Output `json:"outputs,omitempty"`
}
// FileRef represents a file reference.
type FileRef struct {
// File is the path to the referenced file. This can be a direct path to a file
// or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML
// files within the "manifest" directory.
File Expression `json:"file,omitempty"`
}
// ActionResourceRef contains resource reference options for an action.
// +kubebuilder:not:={required:{file,resource}}
type ActionResourceRef struct {
FileRef `json:",inline"`
// Resource provides a resource to be applied.
// +kubebuilder:validation:XEmbeddedResource
// +kubebuilder:pruning:PreserveUnknownFields
// +optional
Resource *unstructured.Unstructured `json:"resource,omitempty"`
// ActionInlineResource `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
}
// ActionTimeout contains timeout options for an action.
type ActionTimeout struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
}
// Apply represents a set of configurations or resources that
// should be applied during testing.
type Apply struct {
ActionBindings `json:",inline"`
ActionClusters `json:",inline"`
ActionDryRun `json:",inline"`
ActionExpectations `json:",inline"`
ActionOutputs `json:",inline"`
ActionResourceRef `json:",inline"`
ActionTimeout `json:",inline"`
}
// Assert represents a test condition that is expected to hold true
// during the testing process.
type Assert struct {
ActionBindings `json:",inline"`
ActionCheckRef `json:",inline"`
ActionClusters `json:",inline"`
ActionTimeout `json:",inline"`
}
// Command describes a command to run as a part of a test step.
type Command struct {
ActionBindings `json:",inline"`
ActionCheck `json:",inline"`
ActionClusters `json:",inline"`
ActionEnv `json:",inline"`
ActionOutputs `json:",inline"`
ActionTimeout `json:",inline"`
// Entrypoint is the command entry point to run.
Entrypoint string `json:"entrypoint"`
// Args is the command arguments.
// +optional
Args []string `json:"args,omitempty"`
// WorkDir is the working directory for command.
// +optional
WorkDir *string `json:"workDir,omitempty"`
}
// Create represents a set of resources that should be created.
// If a resource already exists in the cluster it will fail.
type Create struct {
ActionBindings `json:",inline"`
ActionClusters `json:",inline"`
ActionDryRun `json:",inline"`
ActionExpectations `json:",inline"`
ActionOutputs `json:",inline"`
ActionResourceRef `json:",inline"`
ActionTimeout `json:",inline"`
}
// Delete is a reference to an object that should be deleted
// +kubebuilder:not:={required:{file,ref}}
type Delete struct {
ActionBindings `json:",inline"`
ActionClusters `json:",inline"`
ActionExpectations `json:",inline"`
ActionTimeout `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// File is the path to the referenced file. This can be a direct path to a file
// or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML
// files within the "manifest" directory.
// +optional
File Expression `json:"file,omitempty"`
// Ref determines objects to be deleted.
// +optional
Ref *ObjectReference `json:"ref,omitempty"`
// DeletionPropagationPolicy decides if a deletion will propagate to the dependents of
// the object, and how the garbage collector will handle the propagation.
// Overrides the deletion propagation policy set in the Configuration, the Test and the TestStep.
// +optional
// +kubebuilder:validation:Enum:=Orphan;Background;Foreground
DeletionPropagationPolicy *metav1.DeletionPropagation `json:"deletionPropagationPolicy,omitempty"`
}
// Describe defines how to describe resources.
type Describe struct {
ActionClusters `json:",inline"`
ActionObject `json:",inline"`
ActionTimeout `json:",inline"`
// Show Events indicates whether to include related events.
// +optional
ShowEvents *bool `json:"showEvents,omitempty"`
}
// Error represents an anticipated error condition that may arise during testing.
// Instead of treating such an error as a test failure, it acknowledges it as expected.
type Error struct {
ActionBindings `json:",inline"`
ActionCheckRef `json:",inline"`
ActionClusters `json:",inline"`
ActionTimeout `json:",inline"`
}
// Events defines how to collect events.
type Events struct {
ActionClusters `json:",inline"`
ActionFormat `json:",inline"`
ActionObjectSelector `json:",inline"`
ActionTimeout `json:",inline"`
}
// Get defines how to get resources.
type Get struct {
ActionClusters `json:",inline"`
ActionFormat `json:",inline"`
ActionObject `json:",inline"`
ActionTimeout `json:",inline"`
}
// Patch represents a set of resources that should be patched.
// If a resource doesn't exist yet in the cluster it will fail.
type Patch struct {
ActionBindings `json:",inline"`
ActionClusters `json:",inline"`
ActionDryRun `json:",inline"`
ActionExpectations `json:",inline"`
ActionOutputs `json:",inline"`
ActionResourceRef `json:",inline"`
ActionTimeout `json:",inline"`
}
// PodLogs defines how to collect pod logs.
type PodLogs struct {
ActionClusters `json:",inline"`
ActionObjectSelector `json:",inline"`
ActionTimeout `json:",inline"`
// Container in pod to get logs from else --all-containers is used.
// +optional
Container Expression `json:"container,omitempty"`
// Tail is the number of last lines to collect from pods. If omitted or zero,
// then the default is 10 if you use a selector, or -1 (all) if you use a pod name.
// This matches default behavior of `kubectl logs`.
// +optional
Tail *int `json:"tail,omitempty"`
}
// Proxy defines how to get resources.
type Proxy struct {
ActionClusters `json:",inline"`
ActionOutputs `json:",inline"`
ActionTimeout `json:",inline"`
ObjectName `json:",inline"`
ObjectType `json:",inline"`
// TargetPort defines the target port to proxy the request.
// +optional
TargetPort Expression `json:"port,omitempty"`
// TargetPath defines the target path to proxy the request.
// +optional
TargetPath Expression `json:"path,omitempty"`
}
// Script describes a script to run as a part of a test step.
type Script struct {
ActionBindings `json:",inline"`
ActionCheck `json:",inline"`
ActionClusters `json:",inline"`
ActionEnv `json:",inline"`
ActionOutputs `json:",inline"`
ActionTimeout `json:",inline"`
// Content defines a shell script (run with "sh -c ...").
// +optional
Content string `json:"content,omitempty"`
// WorkDir is the working directory for script.
// +optional
WorkDir *string `json:"workDir,omitempty"`
}
// Sleep represents a duration while nothing happens.
type Sleep struct {
// Duration is the delay used for sleeping.
Duration metav1.Duration `json:"duration"`
}
// Update represents a set of resources that should be updated.
// If a resource does not exist in the cluster it will fail.
type Update struct {
ActionBindings `json:",inline"`
ActionClusters `json:",inline"`
ActionDryRun `json:",inline"`
ActionExpectations `json:",inline"`
ActionOutputs `json:",inline"`
ActionResourceRef `json:",inline"`
ActionTimeout `json:",inline"`
}
// Wait specifies how to perform wait operations on resources.
type Wait struct {
ActionTimeout `json:",inline"`
ActionFormat `json:",inline"`
ActionClusters `json:",inline"`
ActionObject `json:",inline"`
// WaitFor specifies the condition to wait for.
WaitFor `json:"for"`
}
// WaitFor specifies the condition to wait for.
type WaitFor struct {
// Deletion specifies parameters for waiting on a resource's deletion.
// +optional
Deletion *WaitForDeletion `json:"deletion,omitempty"`
// Condition specifies the condition to wait for.
// +optional
Condition *WaitForCondition `json:"condition,omitempty"`
// JsonPath specifies the json path condition to wait for.
// +optional
JsonPath *WaitForJsonPath `json:"jsonPath,omitempty"`
}
// WaitForCondition represents parameters for waiting on a specific condition of a resource.
type WaitForCondition struct {
// Name defines the specific condition to wait for, e.g., "Available", "Ready".
Name Expression `json:"name"`
// Value defines the specific condition status to wait for, e.g., "True", "False".
// +optional
Value *Expression `json:"value,omitempty"`
}
// WaitForDeletion represents parameters for waiting on a resource's deletion.
type WaitForDeletion struct{}
// WaitForJsonPath represents parameters for waiting on a json path of a resource.
type WaitForJsonPath struct {
// Path defines the json path to wait for, e.g. '{.status.phase}'.
Path Expression `json:"path"`
// Value defines the expected value to wait for, e.g., "Running".
// +optional
Value *Expression `json:"value,omitempty"`
}

8
pkg/apis/v1alpha1/any.go Normal file
View File

@ -0,0 +1,8 @@
package v1alpha1
import (
"github.com/kyverno/kyverno-json/pkg/apis/policy/v1alpha1"
)
// Any represents any type.
type Any = v1alpha1.Any

View File

@ -0,0 +1,40 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Apply represents a set of configurations or resources that
// should be applied during testing.
type Apply struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Outputs defines output bindings.
// +optional
Outputs []Output `json:"outputs,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// FileRefOrResource provides a reference to the resources to be applied.
FileRefOrResource `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// DryRun determines whether the file should be applied in dry run mode.
// +optional
DryRun *bool `json:"dryRun,omitempty"`
// Expect defines a list of matched checks to validate the operation outcome.
// +optional
Expect []Expectation `json:"expect,omitempty"`
}

View File

@ -0,0 +1,28 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Assert represents a test condition that is expected to hold true
// during the testing process.
type Assert struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// FileRefOrAssert provides a reference to the assertion.
FileRefOrCheck `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
}

View File

@ -0,0 +1,27 @@
package v1alpha1
import (
"fmt"
"regexp"
)
var identifier = regexp.MustCompile(`^(?:\w+|\(.+\))$`)
// Binding represents a key/value set as a binding in an executing test.
type Binding struct {
// Name the name of the binding.
// +kubebuilder:validation:Pattern=`^(?:\w+|\(.+\))$`
Name string `json:"name"`
// Value value of the binding.
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
Value Any `json:"value"`
}
func (b Binding) CheckName() error {
if !identifier.MatchString(b.Name) {
return fmt.Errorf("invalid name %s", b.Name)
}
return nil
}

View File

@ -9,8 +9,8 @@ import (
func TestBinding_CheckName(t *testing.T) { func TestBinding_CheckName(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
bindingName Expression bindingName string
bindingValue Projection bindingValue Any
wantErr bool wantErr bool
}{{ }{{
name: "empty", name: "empty",

View File

@ -0,0 +1,92 @@
package v1alpha1
// Catch defines actions to be executed on failure.
type Catch struct {
// Description contains a description of the operation.
// +optional
Description string `json:"description,omitempty"`
// PodLogs determines the pod logs collector to execute.
// +optional
PodLogs *PodLogs `json:"podLogs,omitempty"`
// Events determines the events collector to execute.
// +optional
Events *Events `json:"events,omitempty"`
// Describe determines the resource describe collector to execute.
// +optional
Describe *Describe `json:"describe,omitempty"`
// Wait determines the resource wait collector to execute.
// +optional
Wait *Wait `json:"wait,omitempty"`
// Get determines the resource get collector to execute.
// +optional
Get *Get `json:"get,omitempty"`
// Delete represents a deletion operation.
// +optional
Delete *Delete `json:"delete,omitempty"`
// Command defines a command to run.
// +optional
Command *Command `json:"command,omitempty"`
// Script defines a script to run.
// +optional
Script *Script `json:"script,omitempty"`
// Sleep defines zzzz.
// +optional
Sleep *Sleep `json:"sleep,omitempty"`
}
func (c *Catch) Bindings() []Binding {
switch {
case c.Command != nil:
return c.Command.Bindings
case c.Delete != nil:
return c.Delete.Bindings
case c.Describe != nil:
return nil
case c.Events != nil:
return nil
case c.Get != nil:
return nil
case c.PodLogs != nil:
return nil
case c.Script != nil:
return c.Script.Bindings
case c.Sleep != nil:
return nil
case c.Wait != nil:
return nil
}
panic("missing binding operation type handler")
}
func (c *Catch) Outputs() []Output {
switch {
case c.Command != nil:
return c.Command.Outputs
case c.Delete != nil:
return nil
case c.Describe != nil:
return nil
case c.Events != nil:
return nil
case c.Get != nil:
return nil
case c.PodLogs != nil:
return nil
case c.Script != nil:
return c.Script.Outputs
case c.Sleep != nil:
return nil
case c.Wait != nil:
return nil
}
panic("missing output operation type handler")
}

View File

@ -0,0 +1,168 @@
package v1alpha1
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCatch_Bindings(t *testing.T) {
type fields struct {
PodLogs *PodLogs
Events *Events
Describe *Describe
Wait *Wait
Get *Get
Delete *Delete
Command *Command
Script *Script
Sleep *Sleep
}
tests := []struct {
name string
fields fields
want int
}{{
fields: fields{
Command: &Command{
Bindings: []Binding{{"foo", Any{Value: "bar"}}},
},
},
want: 1,
}, {
fields: fields{
Delete: &Delete{
Bindings: []Binding{{"foo", Any{Value: "bar"}}},
},
},
want: 1,
}, {
fields: fields{
Describe: &Describe{},
},
}, {
fields: fields{
Events: &Events{},
},
}, {
fields: fields{
Get: &Get{},
},
}, {
fields: fields{
PodLogs: &PodLogs{},
},
}, {
fields: fields{
Script: &Script{
Bindings: []Binding{{"foo", Any{Value: "bar"}}},
},
},
want: 1,
}, {
fields: fields{
Sleep: &Sleep{},
},
}, {
fields: fields{
Wait: &Wait{},
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Catch{
PodLogs: tt.fields.PodLogs,
Events: tt.fields.Events,
Describe: tt.fields.Describe,
Wait: tt.fields.Wait,
Get: tt.fields.Get,
Delete: tt.fields.Delete,
Command: tt.fields.Command,
Script: tt.fields.Script,
Sleep: tt.fields.Sleep,
}
got := c.Bindings()
assert.Equal(t, tt.want, len(got))
})
}
assert.Panics(t, func() { (&Catch{}).Bindings() })
}
func TestCatch_Outputs(t *testing.T) {
type fields struct {
PodLogs *PodLogs
Events *Events
Describe *Describe
Wait *Wait
Get *Get
Delete *Delete
Command *Command
Script *Script
Sleep *Sleep
}
tests := []struct {
name string
fields fields
want int
}{{
fields: fields{
Command: &Command{
Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
},
},
want: 1,
}, {
fields: fields{
Delete: &Delete{},
},
}, {
fields: fields{
Describe: &Describe{},
},
}, {
fields: fields{
Events: &Events{},
},
}, {
fields: fields{
Get: &Get{},
},
}, {
fields: fields{
PodLogs: &PodLogs{},
},
}, {
fields: fields{
Script: &Script{
Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
},
},
want: 1,
}, {
fields: fields{
Sleep: &Sleep{},
},
}, {
fields: fields{
Wait: &Wait{},
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Catch{
PodLogs: tt.fields.PodLogs,
Events: tt.fields.Events,
Describe: tt.fields.Describe,
Wait: tt.fields.Wait,
Get: tt.fields.Get,
Delete: tt.fields.Delete,
Command: tt.fields.Command,
Script: tt.fields.Script,
Sleep: tt.fields.Sleep,
}
got := c.Outputs()
assert.Equal(t, tt.want, len(got))
})
}
assert.Panics(t, func() { (&Catch{}).Outputs() })
}

View File

@ -0,0 +1,4 @@
package v1alpha1
// Check represents a check to be applied on the result of an operation.
type Check = Any

View File

@ -0,0 +1,10 @@
package v1alpha1
type Cluster struct {
// Kubeconfig is the path to the referenced file.
Kubeconfig string `json:"kubeconfig"`
// Context is the name of the context to use.
// +optional
Context string `json:"context,omitempty"`
}

View File

@ -0,0 +1,43 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Command describes a command to run as a part of a test step.
type Command struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Outputs defines output bindings.
// +optional
Outputs []Output `json:"outputs,omitempty"`
// Env defines additional environment variables.
// +optional
Env []Binding `json:"env,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// Entrypoint is the command entry point to run.
Entrypoint string `json:"entrypoint"`
// Args is the command arguments.
// +optional
Args []string `json:"args,omitempty"`
// SkipLogOutput removes the output from the command. Useful for sensitive logs or to reduce noise.
// +optional
SkipLogOutput bool `json:"skipLogOutput,omitempty"`
// Check is an assertion tree to validate the operation outcome.
// +optional
Check *Check `json:"check,omitempty"`
}

View File

@ -20,122 +20,3 @@ type Configuration struct {
// Configuration spec. // Configuration spec.
Spec ConfigurationSpec `json:"spec"` Spec ConfigurationSpec `json:"spec"`
} }
// ConfigurationSpec contains the configuration used to run tests.
type ConfigurationSpec struct {
// Global timeouts configuration. Applies to all tests/test steps if not overridden.
// +optional
// +kubebuilder:default:={}
Timeouts DefaultTimeouts `json:"timeouts"`
// If set, do not delete the resources after running the tests (implies SkipClusterDelete).
// +optional
SkipDelete bool `json:"skipDelete,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
// +kubebuilder:default:=true
Template bool `json:"template"`
// Compiler defines the default compiler to use when evaluating expressions.
// +optional
Compiler *Compiler `json:"compiler,omitempty"`
// FailFast determines whether the test should stop upon encountering the first failure.
// +optional
FailFast bool `json:"failFast,omitempty"`
// The maximum number of tests to run at once.
// +kubebuilder:validation:Format:=int
// +kubebuilder:validation:Minimum:=1
// +optional
Parallel *int `json:"parallel,omitempty"`
// DeletionPropagationPolicy decides if a deletion will propagate to the dependents of
// the object, and how the garbage collector will handle the propagation.
// +optional
// +kubebuilder:validation:Enum:=Orphan;Background;Foreground
// +kubebuilder:default:=Background
DeletionPropagationPolicy metav1.DeletionPropagation `json:"deletionPropagationPolicy,omitempty"`
// ReportFormat determines test report format (JSON, XML, JUNIT-TEST, JUNIT-STEP, JUNIT-OPERATION, nil) nil == no report.
// maps to report.Type, however we don't want generated.deepcopy to have reference to it.
// +optional
// +kubebuilder:validation:Enum:=JSON;XML;JUNIT-TEST;JUNIT-STEP;JUNIT-OPERATION;
ReportFormat ReportFormatType `json:"reportFormat,omitempty"`
// ReportPath defines the path.
// +optional
ReportPath string `json:"reportPath,omitempty"`
// ReportName defines the name of report to create. It defaults to "chainsaw-report".
// +optional
// +kubebuilder:default:="chainsaw-report"
ReportName string `json:"reportName,omitempty"`
// Namespace defines the namespace to use for tests.
// If not specified, every test will execute in a random ephemeral namespace
// unless the namespace is overridden in a the test spec.
// +optional
Namespace string `json:"namespace,omitempty"`
// NamespaceTemplateCompiler defines the default compiler to use when evaluating expressions.
// +optional
NamespaceTemplateCompiler *Compiler `json:"namespaceTemplateCompiler,omitempty"`
// NamespaceTemplate defines a template to create the test namespace.
// +optional
NamespaceTemplate *Projection `json:"namespaceTemplate,omitempty"`
// FullName makes use of the full test case folder path instead of the folder name.
// +optional
FullName bool `json:"fullName,omitempty"`
// ExcludeTestRegex is used to exclude tests based on a regular expression.
// +optional
ExcludeTestRegex string `json:"excludeTestRegex,omitempty"`
// IncludeTestRegex is used to include tests based on a regular expression.
// +optional
IncludeTestRegex string `json:"includeTestRegex,omitempty"`
// RepeatCount indicates how many times the tests should be executed.
// +kubebuilder:validation:Format:=int
// +kubebuilder:validation:Minimum:=1
// +optional
RepeatCount *int `json:"repeatCount,omitempty"`
// TestFile is the name of the file containing the test to run.
// If no extension is provided, chainsaw will try with .yaml first and .yml if needed.
// +kubebuilder:default:="chainsaw-test"
// +optional
TestFile string `json:"testFile,omitempty"`
// ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.
// +optional
ForceTerminationGracePeriod *metav1.Duration `json:"forceTerminationGracePeriod,omitempty"`
// DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.
// +optional
DelayBeforeCleanup *metav1.Duration `json:"delayBeforeCleanup,omitempty"`
// Clusters holds a registry to clusters to support multi-cluster tests.
// +optional
Clusters Clusters `json:"clusters,omitempty"`
// Catch defines what the tests steps will execute when an error happens.
// This will be combined with catch handlers defined at the test and step levels.
// +optional
Catch []CatchFinally `json:"catch,omitempty"`
}
type ReportFormatType string
const (
JSONFormat ReportFormatType = "JSON"
XMLFormat ReportFormatType = "XML"
JUnitTestFormat ReportFormatType = "JUNIT-TEST"
JUnitStepFormat ReportFormatType = "JUNIT-STEP"
JUnitOperationFormat ReportFormatType = "JUNIT-OPERATION"
NoReport ReportFormatType = ""
)

View File

@ -0,0 +1,102 @@
package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
type ReportFormatType string
const (
JSONFormat ReportFormatType = "JSON"
XMLFormat ReportFormatType = "XML"
NoReport ReportFormatType = ""
)
// ConfigurationSpec contains the configuration used to run tests.
type ConfigurationSpec struct {
// Global timeouts configuration. Applies to all tests/test steps if not overridden.
// +optional
Timeouts Timeouts `json:"timeouts"`
// If set, do not delete the resources after running the tests (implies SkipClusterDelete).
// +optional
SkipDelete bool `json:"skipDelete,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// FailFast determines whether the test should stop upon encountering the first failure.
// +optional
FailFast bool `json:"failFast,omitempty"`
// The maximum number of tests to run at once.
// +kubebuilder:validation:Format:=int
// +kubebuilder:validation:Minimum:=1
// +optional
Parallel *int `json:"parallel,omitempty"`
// ReportFormat determines test report format (JSON|XML|nil) nil == no report.
// maps to report.Type, however we don't want generated.deepcopy to have reference to it.
// +optional
// +kubebuilder:validation:Enum:=JSON;XML;
ReportFormat ReportFormatType `json:"reportFormat,omitempty"`
// ReportPath defines the path.
// +optional
ReportPath string `json:"reportPath,omitempty"`
// ReportName defines the name of report to create. It defaults to "chainsaw-report".
// +optional
// +kubebuilder:default:="chainsaw-report"
ReportName string `json:"reportName,omitempty"`
// Namespace defines the namespace to use for tests.
// If not specified, every test will execute in a random ephemeral namespace
// unless the namespace is overridden in a the test spec.
// +optional
Namespace string `json:"namespace,omitempty"`
// NamespaceTemplate defines a template to create the test namespace.
// +optional
NamespaceTemplate *Any `json:"namespaceTemplate,omitempty"`
// FullName makes use of the full test case folder path instead of the folder name.
// +optional
FullName bool `json:"fullName,omitempty"`
// ExcludeTestRegex is used to exclude tests based on a regular expression.
// +optional
ExcludeTestRegex string `json:"excludeTestRegex,omitempty"`
// IncludeTestRegex is used to include tests based on a regular expression.
// +optional
IncludeTestRegex string `json:"includeTestRegex,omitempty"`
// RepeatCount indicates how many times the tests should be executed.
// +kubebuilder:validation:Format:=int
// +kubebuilder:validation:Minimum:=1
// +optional
RepeatCount *int `json:"repeatCount,omitempty"`
// TestFile is the name of the file containing the test to run.
// If no extension is provided, chainsaw will try with .yaml first and .yml if needed.
// +kubebuilder:default:="chainsaw-test"
// +optional
TestFile string `json:"testFile,omitempty"`
// ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.
// +optional
ForceTerminationGracePeriod *metav1.Duration `json:"forceTerminationGracePeriod,omitempty"`
// DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.
// +optional
DelayBeforeCleanup *metav1.Duration `json:"delayBeforeCleanup,omitempty"`
// Clusters holds a registry to clusters to support multi-cluster tests.
// +optional
Clusters map[string]Cluster `json:"clusters,omitempty"`
// Catch defines what the tests steps will execute when an error happens.
// This will be combined with catch handlers defined at the test and step levels.
// +optional
Catch []Catch `json:"catch,omitempty"`
}

View File

@ -0,0 +1,40 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Create represents a set of resources that should be created.
// If a resource already exists in the cluster it will fail.
type Create struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Outputs defines output bindings.
// +optional
Outputs []Output `json:"outputs,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// FileRefOrResource provides a reference to the file containing the resources to be created.
FileRefOrResource `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// DryRun determines whether the file should be applied in dry run mode.
// +optional
DryRun *bool `json:"dryRun,omitempty"`
// Expect defines a list of matched checks to validate the operation outcome.
// +optional
Expect []Expectation `json:"expect,omitempty"`
}

View File

@ -0,0 +1,31 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Delete is a reference to an object that should be deleted
type Delete struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// ObjectReference determines objects to be deleted.
ObjectReference `json:"ref"`
// Expect defines a list of matched checks to validate the operation outcome.
// +optional
Expect []Expectation `json:"expect,omitempty"`
}

View File

@ -0,0 +1,26 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Describe defines how to describe resources.
type Describe struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// ResourceReference referenced resource type.
ResourceReference `json:",inline"`
// ObjectLabelsSelector determines the selection process of referenced objects.
ObjectLabelsSelector `json:",inline"`
// Show Events indicates whether to include related events.
// +optional
ShowEvents *bool `json:"showEvents,omitempty"`
}

View File

@ -0,0 +1,28 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Error represents an anticipated error condition that may arise during testing.
// Instead of treating such an error as a test failure, it acknowledges it as expected.
type Error struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// FileRefOrAssert provides a reference to the expected error.
FileRefOrCheck `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
}

View File

@ -0,0 +1,23 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Events defines how to collect events.
type Events struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// ObjectLabelsSelector determines the selection process of referenced objects.
ObjectLabelsSelector `json:",inline"`
// Format determines the output format (json or yaml).
// +optional
Format Format `json:"format,omitempty"`
}

View File

@ -0,0 +1,12 @@
package v1alpha1
// Expectation represents a check to be applied on the result of an operation
// with a match filter to determine if the verification should be considered.
type Expectation struct {
// Match defines the matching statement.
// +optional
Match *Match `json:"match,omitempty"`
// Check defines the verification statement.
Check Check `json:"check"`
}

View File

@ -0,0 +1,9 @@
package v1alpha1
// FileRef represents a file reference.
type FileRef struct {
// File is the path to the referenced file. This can be a direct path to a file
// or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML
// files within the "manifest" directory.
File string `json:"file,omitempty"`
}

View File

@ -0,0 +1,12 @@
package v1alpha1
// FileRefOrCheck represents a file reference or resource.
type FileRefOrCheck struct {
// FileRef provides a reference to the file containing the resources to be applied.
// +optional
FileRef `json:",inline"`
// Check provides a check used in assertions.
// +optional
Check *Check `json:"resource,omitempty"`
}

View File

@ -0,0 +1,18 @@
package v1alpha1
import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// FileRefOrResource represents a file reference or resource.
type FileRefOrResource struct {
// FileRef provides a reference to the file containing the resources to be applied.
// +optional
FileRef `json:",inline"`
// Resource provides a resource to be applied.
// +kubebuilder:validation:XEmbeddedResource
// +kubebuilder:pruning:PreserveUnknownFields
// +optional
Resource *unstructured.Unstructured `json:"resource,omitempty"`
}

View File

@ -1,24 +1,11 @@
package v1alpha1 package v1alpha1
// CatchFinally defines actions to be executed in catch, finally and cleanup blocks. // Finally defines actions to be executed at the end of a test.
// +kubebuilder:oneOf:={required:{command}} type Finally struct {
// +kubebuilder:oneOf:={required:{delete}}
// +kubebuilder:oneOf:={required:{describe}}
// +kubebuilder:oneOf:={required:{events}}
// +kubebuilder:oneOf:={required:{get}}
// +kubebuilder:oneOf:={required:{podLogs}}
// +kubebuilder:oneOf:={required:{script}}
// +kubebuilder:oneOf:={required:{sleep}}
// +kubebuilder:oneOf:={required:{wait}}
type CatchFinally struct {
// Description contains a description of the operation. // Description contains a description of the operation.
// +optional // +optional
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
// Compiler defines the default compiler to use when evaluating expressions.
// +optional
Compiler *Compiler `json:"compiler,omitempty"`
// PodLogs determines the pod logs collector to execute. // PodLogs determines the pod logs collector to execute.
// +optional // +optional
PodLogs *PodLogs `json:"podLogs,omitempty"` PodLogs *PodLogs `json:"podLogs,omitempty"`
@ -56,7 +43,7 @@ type CatchFinally struct {
Sleep *Sleep `json:"sleep,omitempty"` Sleep *Sleep `json:"sleep,omitempty"`
} }
func (f *CatchFinally) Bindings() []Binding { func (f *Finally) Bindings() []Binding {
switch { switch {
case f.Command != nil: case f.Command != nil:
return f.Command.Bindings return f.Command.Bindings
@ -80,7 +67,7 @@ func (f *CatchFinally) Bindings() []Binding {
panic("missing binding operation type handler") panic("missing binding operation type handler")
} }
func (f *CatchFinally) Outputs() []Output { func (f *Finally) Outputs() []Output {
switch { switch {
case f.Command != nil: case f.Command != nil:
return f.Command.Outputs return f.Command.Outputs

View File

@ -25,14 +25,14 @@ func TestFinally_Bindings(t *testing.T) {
}{{ }{{
fields: fields{ fields: fields{
Command: &Command{ Command: &Command{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
fields: fields{ fields: fields{
Delete: &Delete{ Delete: &Delete{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
@ -55,7 +55,7 @@ func TestFinally_Bindings(t *testing.T) {
}, { }, {
fields: fields{ fields: fields{
Script: &Script{ Script: &Script{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
@ -70,7 +70,7 @@ func TestFinally_Bindings(t *testing.T) {
}} }}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
c := &CatchFinally{ c := &Finally{
PodLogs: tt.fields.PodLogs, PodLogs: tt.fields.PodLogs,
Events: tt.fields.Events, Events: tt.fields.Events,
Describe: tt.fields.Describe, Describe: tt.fields.Describe,
@ -85,7 +85,7 @@ func TestFinally_Bindings(t *testing.T) {
assert.Equal(t, tt.want, len(got)) assert.Equal(t, tt.want, len(got))
}) })
} }
assert.Panics(t, func() { (&CatchFinally{}).Bindings() }) assert.Panics(t, func() { (&Finally{}).Bindings() })
} }
func TestFinally_Outputs(t *testing.T) { func TestFinally_Outputs(t *testing.T) {
@ -107,7 +107,7 @@ func TestFinally_Outputs(t *testing.T) {
}{{ }{{
fields: fields{ fields: fields{
Command: &Command{ Command: &Command{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
@ -134,7 +134,7 @@ func TestFinally_Outputs(t *testing.T) {
}, { }, {
fields: fields{ fields: fields{
Script: &Script{ Script: &Script{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
@ -149,7 +149,7 @@ func TestFinally_Outputs(t *testing.T) {
}} }}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
c := &CatchFinally{ c := &Finally{
PodLogs: tt.fields.PodLogs, PodLogs: tt.fields.PodLogs,
Events: tt.fields.Events, Events: tt.fields.Events,
Describe: tt.fields.Describe, Describe: tt.fields.Describe,
@ -164,5 +164,5 @@ func TestFinally_Outputs(t *testing.T) {
assert.Equal(t, tt.want, len(got)) assert.Equal(t, tt.want, len(got))
}) })
} }
assert.Panics(t, func() { (&CatchFinally{}).Outputs() }) assert.Panics(t, func() { (&Finally{}).Outputs() })
} }

View File

@ -0,0 +1,5 @@
package v1alpha1
// Format determines the output format (json or yaml).
// +kubebuilder:validation:Pattern=`^(?:json|yaml|\(.+\))$`
type Format string

26
pkg/apis/v1alpha1/get.go Normal file
View File

@ -0,0 +1,26 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Get defines how to get resources.
type Get struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// ResourceReference referenced resource type.
ResourceReference `json:",inline"`
// ObjectLabelsSelector determines the selection process of referenced objects.
ObjectLabelsSelector `json:",inline"`
// Format determines the output format (json or yaml).
// +optional
Format Format `json:"format,omitempty"`
}

View File

@ -0,0 +1,4 @@
package v1alpha1
// Match represents a match condition against an evaluated object.
type Match = Any

View File

@ -0,0 +1,20 @@
package v1alpha1
// ObjectLabelsSelector represents a strategy to select objects.
// For a single object name and namespace are used to identify the object.
// For multiple objects use selector.
type ObjectLabelsSelector struct {
// Namespace of the referent.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
// +optional
Namespace string `json:"namespace,omitempty"`
// Name of the referent.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// +optional
Name string `json:"name,omitempty"`
// Selector defines labels selector.
// +optional
Selector string `json:"selector,omitempty"`
}

View File

@ -0,0 +1,12 @@
package v1alpha1
// ObjectReference represents one or more objects with a specific apiVersion and kind.
// For a single object name and namespace are used to identify the object.
// For multiple objects use labels.
type ObjectReference struct {
// ObjectType determines the type of referenced objects.
ObjectType `json:",inline"`
// ObjectSelector determines the selection process of referenced objects.
ObjectSelector `json:",inline"`
}

View File

@ -0,0 +1,20 @@
package v1alpha1
// ObjectSelector represents a strategy to select objects.
// For a single object name and namespace are used to identify the object.
// For multiple objects use labels.
type ObjectSelector struct {
// Namespace of the referent.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
// +optional
Namespace string `json:"namespace,omitempty"`
// Name of the referent.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// +optional
Name string `json:"name,omitempty"`
// Label selector to match objects to delete
// +optional
Labels map[string]string `json:"labels,omitempty"`
}

View File

@ -0,0 +1,11 @@
package v1alpha1
// ObjectType represents a specific apiVersion and kind.
type ObjectType struct {
// API version of the referent.
APIVersion string `json:"apiVersion"`
// Kind of the referent.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
Kind string `json:"kind"`
}

View File

@ -1,7 +1,7 @@
package v1alpha1 package v1alpha1
// OperationBase defines common elements to all operations. // Operation defines a single operation, only one action is permitted for a given operation.
type OperationBase struct { type Operation struct {
// Description contains a description of the operation. // Description contains a description of the operation.
// +optional // +optional
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
@ -11,32 +11,6 @@ type OperationBase struct {
// +optional // +optional
ContinueOnError *bool `json:"continueOnError,omitempty"` ContinueOnError *bool `json:"continueOnError,omitempty"`
// Compiler defines the default compiler to use when evaluating expressions.
// +optional
Compiler *Compiler `json:"compiler,omitempty"`
}
// Operation defines a single operation, only one action is permitted for a given operation.
// +kubebuilder:oneOf:={required:{apply}}
// +kubebuilder:oneOf:={required:{assert}}
// +kubebuilder:oneOf:={required:{command}}
// +kubebuilder:oneOf:={required:{create}}
// +kubebuilder:oneOf:={required:{delete}}
// +kubebuilder:oneOf:={required:{describe}}
// +kubebuilder:oneOf:={required:{error}}
// +kubebuilder:oneOf:={required:{events}}
// +kubebuilder:oneOf:={required:{patch}}
// +kubebuilder:oneOf:={required:{podLogs}}
// +kubebuilder:oneOf:={required:{proxy}}
// +kubebuilder:oneOf:={required:{script}}
// +kubebuilder:oneOf:={required:{sleep}}
// +kubebuilder:oneOf:={required:{update}}
// +kubebuilder:oneOf:={required:{wait}}
type Operation struct {
// OperationBase defines common elements to all operations.
// +optional
OperationBase `json:",inline"`
// Apply represents resources that should be applied for this test step. This can include things // Apply represents resources that should be applied for this test step. This can include things
// like configuration settings or any other resources that need to be available during the test. // like configuration settings or any other resources that need to be available during the test.
// +optional // +optional
@ -58,35 +32,15 @@ type Operation struct {
// +optional // +optional
Delete *Delete `json:"delete,omitempty"` Delete *Delete `json:"delete,omitempty"`
// Describe determines the resource describe collector to execute.
// +optional
Describe *Describe `json:"describe,omitempty"`
// Error represents the expected errors for this test step. If any of these errors occur, the test // Error represents the expected errors for this test step. If any of these errors occur, the test
// will consider them as expected; otherwise, they will be treated as test failures. // will consider them as expected; otherwise, they will be treated as test failures.
// +optional // +optional
Error *Error `json:"error,omitempty"` Error *Error `json:"error,omitempty"`
// Events determines the events collector to execute.
// +optional
Events *Events `json:"events,omitempty"`
// Get determines the resource get collector to execute.
// +optional
Get *Get `json:"get,omitempty"`
// Patch represents a patch operation. // Patch represents a patch operation.
// +optional // +optional
Patch *Patch `json:"patch,omitempty"` Patch *Patch `json:"patch,omitempty"`
// PodLogs determines the pod logs collector to execute.
// +optional
PodLogs *PodLogs `json:"podLogs,omitempty"`
// Proxy runs a proxy request.
// +optional
Proxy *Proxy `json:"proxy,omitempty"`
// Script defines a script to run. // Script defines a script to run.
// +optional // +optional
Script *Script `json:"script,omitempty"` Script *Script `json:"script,omitempty"`
@ -116,20 +70,10 @@ func (o *Operation) Bindings() []Binding {
return o.Create.Bindings return o.Create.Bindings
case o.Delete != nil: case o.Delete != nil:
return o.Delete.Bindings return o.Delete.Bindings
case o.Describe != nil:
return nil
case o.Error != nil: case o.Error != nil:
return o.Error.Bindings return o.Error.Bindings
case o.Events != nil:
return nil
case o.Get != nil:
return nil
case o.Patch != nil: case o.Patch != nil:
return o.Patch.Bindings return o.Patch.Bindings
case o.PodLogs != nil:
return nil
case o.Proxy != nil:
return nil
case o.Script != nil: case o.Script != nil:
return o.Script.Bindings return o.Script.Bindings
case o.Sleep != nil: case o.Sleep != nil:
@ -154,20 +98,10 @@ func (o *Operation) Outputs() []Output {
return o.Create.Outputs return o.Create.Outputs
case o.Delete != nil: case o.Delete != nil:
return nil return nil
case o.Describe != nil:
return nil
case o.Error != nil: case o.Error != nil:
return nil return nil
case o.Events != nil:
return nil
case o.Get != nil:
return nil
case o.Patch != nil: case o.Patch != nil:
return o.Patch.Outputs return o.Patch.Outputs
case o.PodLogs != nil:
return nil
case o.Proxy != nil:
return o.Proxy.Outputs
case o.Script != nil: case o.Script != nil:
return o.Script.Outputs return o.Script.Outputs
case o.Sleep != nil: case o.Sleep != nil:

View File

@ -7,110 +7,111 @@ import (
) )
func TestOperation_Bindings(t *testing.T) { func TestOperation_Bindings(t *testing.T) {
type fields struct {
Apply *Apply
Assert *Assert
Command *Command
Create *Create
Delete *Delete
Error *Error
Patch *Patch
Script *Script
Sleep *Sleep
Update *Update
Wait *Wait
}
tests := []struct { tests := []struct {
name string name string
operation Operation fields fields
want int want int
}{{ }{{
operation: Operation{ fields: fields{
Apply: &Apply{ Apply: &Apply{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Assert: &Assert{ Assert: &Assert{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Command: &Command{ Command: &Command{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Create: &Create{ Create: &Create{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Delete: &Delete{ Delete: &Delete{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Describe: &Describe{},
},
want: 0,
}, {
operation: Operation{
Error: &Error{ Error: &Error{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Events: &Events{},
},
want: 0,
}, {
operation: Operation{
Get: &Get{},
},
want: 0,
}, {
operation: Operation{
Patch: &Patch{ Patch: &Patch{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
PodLogs: &PodLogs{},
},
want: 0,
}, {
operation: Operation{
Proxy: &Proxy{},
},
want: 0,
}, {
operation: Operation{
Script: &Script{ Script: &Script{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Sleep: &Sleep{}, Sleep: &Sleep{},
}, },
}, { }, {
operation: Operation{ fields: fields{
Update: &Update{ Update: &Update{
ActionBindings: ActionBindings{Bindings: []Binding{{Name: "foo", Value: NewProjection("bar")}}}, Bindings: []Binding{{"foo", Any{Value: "bar"}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Wait: &Wait{}, Wait: &Wait{},
}, },
}} }}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := tt.operation.Bindings() c := &Operation{
Apply: tt.fields.Apply,
Assert: tt.fields.Assert,
Command: tt.fields.Command,
Create: tt.fields.Create,
Delete: tt.fields.Delete,
Error: tt.fields.Error,
Patch: tt.fields.Patch,
Script: tt.fields.Script,
Sleep: tt.fields.Sleep,
Update: tt.fields.Update,
Wait: tt.fields.Wait,
}
got := c.Bindings()
assert.Equal(t, tt.want, len(got)) assert.Equal(t, tt.want, len(got))
}) })
} }
@ -118,96 +119,102 @@ func TestOperation_Bindings(t *testing.T) {
} }
func TestOperation_Outputs(t *testing.T) { func TestOperation_Outputs(t *testing.T) {
type fields struct {
Apply *Apply
Assert *Assert
Command *Command
Create *Create
Delete *Delete
Error *Error
Patch *Patch
Script *Script
Sleep *Sleep
Update *Update
Wait *Wait
}
tests := []struct { tests := []struct {
name string name string
operation Operation fields fields
want int want int
}{{ }{{
operation: Operation{ fields: fields{
Apply: &Apply{ Apply: &Apply{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Assert: &Assert{}, Assert: &Assert{},
}, },
}, { }, {
operation: Operation{ fields: fields{
Command: &Command{ Command: &Command{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Create: &Create{ Create: &Create{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Delete: &Delete{}, Delete: &Delete{},
}, },
}, { }, {
operation: Operation{ fields: fields{
Describe: &Describe{},
},
}, {
operation: Operation{
Error: &Error{}, Error: &Error{},
}, },
}, { }, {
operation: Operation{ fields: fields{
Events: &Events{},
},
}, {
operation: Operation{
Get: &Get{},
},
}, {
operation: Operation{
Patch: &Patch{ Patch: &Patch{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
PodLogs: &PodLogs{},
},
}, {
operation: Operation{
Proxy: &Proxy{},
},
}, {
operation: Operation{
Script: &Script{ Script: &Script{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Sleep: &Sleep{}, Sleep: &Sleep{},
}, },
}, { }, {
operation: Operation{ fields: fields{
Update: &Update{ Update: &Update{
ActionOutputs: ActionOutputs{Outputs: []Output{{Binding: Binding{Name: "foo", Value: NewProjection("bar")}}}}, Outputs: []Output{{Binding: Binding{"foo", Any{Value: "bar"}}}},
}, },
}, },
want: 1, want: 1,
}, { }, {
operation: Operation{ fields: fields{
Wait: &Wait{}, Wait: &Wait{},
}, },
}} }}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := tt.operation.Outputs() c := &Operation{
Apply: tt.fields.Apply,
Assert: tt.fields.Assert,
Command: tt.fields.Command,
Create: tt.fields.Create,
Delete: tt.fields.Delete,
Error: tt.fields.Error,
Patch: tt.fields.Patch,
Script: tt.fields.Script,
Sleep: tt.fields.Sleep,
Update: tt.fields.Update,
Wait: tt.fields.Wait,
}
got := c.Outputs()
assert.Equal(t, tt.want, len(got)) assert.Equal(t, tt.want, len(got))
}) })
} }

View File

@ -0,0 +1,11 @@
package v1alpha1
// Output represents an output binding with a match to determine if the binding must be considered or not.
type Output struct {
// Binding determines the binding to create when the match succeeds.
Binding `json:",inline"`
// Match defines the matching statement.
// +optional
Match *Match `json:"match,omitempty"`
}

View File

@ -0,0 +1,40 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Patch represents a set of resources that should be patched.
// If a resource doesn't exist yet in the cluster it will fail.
type Patch struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Outputs defines output bindings.
// +optional
Outputs []Output `json:"outputs,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// FileRefOrResource provides a reference to the file containing the resources to be patched.
FileRefOrResource `json:",inline"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// DryRun determines whether the file should be applied in dry run mode.
// +optional
DryRun *bool `json:"dryRun,omitempty"`
// Expect defines a list of matched checks to validate the operation outcome.
// +optional
Expect []Expectation `json:"expect,omitempty"`
}

View File

@ -0,0 +1,29 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// PodLogs defines how to collect pod logs.
type PodLogs struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// ObjectLabelsSelector determines the selection process of referenced objects.
ObjectLabelsSelector `json:",inline"`
// Container in pod to get logs from else --all-containers is used.
// +optional
Container string `json:"container,omitempty"`
// Tail is the number of last lines to collect from pods. If omitted or zero,
// then the default is 10 if you use a selector, or -1 (all) if you use a pod name.
// This matches default behavior of `kubectl logs`.
// +optional
Tail *int `json:"tail,omitempty"`
}

View File

@ -1,52 +0,0 @@
package v1alpha1
import (
"encoding/json"
"github.com/kyverno/kyverno-json/pkg/utils/copy"
)
// Projection can be any type.
// +k8s:deepcopy-gen=false
// +kubebuilder:validation:XPreserveUnknownFields
// +kubebuilder:validation:Type:=""
type Projection struct {
_value any
}
func NewProjection(value any) Projection {
return Projection{
_value: value,
}
}
func (a *Projection) Value() any {
return a._value
}
func (a *Projection) MarshalJSON() ([]byte, error) {
return json.Marshal(a._value)
}
func (a *Projection) UnmarshalJSON(data []byte) error {
var v any
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
a._value = v
return nil
}
func (in *Projection) DeepCopyInto(out *Projection) {
out._value = copy.DeepCopy(in._value)
}
func (in *Projection) DeepCopy() *Projection {
if in == nil {
return nil
}
out := new(Projection)
in.DeepCopyInto(out)
return out
}

View File

@ -0,0 +1,18 @@
package v1alpha1
// ResourceReference represents a resource (API), it can be represented with a resource or a kind.
// Optionally an apiVersion can be specified.
type ResourceReference struct {
// API version of the referent.
// +optional
APIVersion string `json:"apiVersion,omitempty"`
// Kind of the referent.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
Kind string `json:"kind,omitempty"`
// Resource name of the referent.
// +optional
Resource string `json:"resource,omitempty"`
}

View File

@ -0,0 +1,40 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Script describes a script to run as a part of a test step.
type Script struct {
// Timeout for the operation. Overrides the global timeout set in the Configuration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Outputs defines output bindings.
// +optional
Outputs []Output `json:"outputs,omitempty"`
// Env defines additional environment variables.
// +optional
Env []Binding `json:"env,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// Content defines a shell script (run with "sh -c ...").
// +optional
Content string `json:"content,omitempty"`
// SkipLogOutput removes the output from the command. Useful for sensitive logs or to reduce noise.
// +optional
SkipLogOutput bool `json:"skipLogOutput,omitempty"`
// Check is an assertion tree to validate the operation outcome.
// +optional
Check *Check `json:"check,omitempty"`
}

View File

@ -0,0 +1,11 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Sleep represents a duration while nothing happens.
type Sleep struct {
// Duration is the delay used for sleeping.
Duration metav1.Duration `json:"duration"`
}

View File

@ -1,137 +0,0 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:storageversion
// StepTemplate is the resource that contains a step definition.
type StepTemplate struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// Test step spec.
Spec StepTemplateSpec `json:"spec"`
}
// StepTemplateSpec defines the spec of a step template.
type StepTemplateSpec struct {
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Try defines what the step will try to execute.
// +kubebuilder:validation:MinItems:=1
Try []Operation `json:"try"`
// Catch defines what the step will execute when an error happens.
// +optional
Catch []CatchFinally `json:"catch,omitempty"`
// Finally defines what the step will execute after the step is terminated.
// +optional
Finally []CatchFinally `json:"finally,omitempty"`
// Cleanup defines what will be executed after the test is terminated.
// +optional
Cleanup []CatchFinally `json:"cleanup,omitempty"`
}
// TestStep contains the test step definition used in a test spec.
// +kubebuilder:not:={required:{use},anyOf:{{required:{try}},{required:{catch}},{required:{finally}},{required:{cleanup}}}}
type TestStep struct {
// Name of the step.
// +optional
Name string `json:"name,omitempty"`
// Use defines a reference to a step template.
Use *Use `json:"use,omitempty"`
// TestStepSpec of the step.
TestStepSpec `json:",inline"`
}
// Use defines a reference to a step template.
type Use struct {
// Template references a step template.
Template string `json:"template"`
// With defines arguments passed to the step template.
// +optional
// +kubebuilder:default:={}
With With `json:"with"`
}
// With defines arguments passed to step templates.
type With struct {
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
}
// TestStepSpec defines the desired state and behavior for each test step.
type TestStepSpec struct {
// Description contains a description of the test step.
// +optional
Description string `json:"description,omitempty"`
// Timeouts for the test step. Overrides the global timeouts set in the Configuration and the timeouts eventually set in the Test.
// +optional
Timeouts *Timeouts `json:"timeouts,omitempty"`
// DeletionPropagationPolicy decides if a deletion will propagate to the dependents of
// the object, and how the garbage collector will handle the propagation.
// Overrides the deletion propagation policy set in both the Configuration and the Test.
// +optional
// +kubebuilder:validation:Enum:=Orphan;Background;Foreground
DeletionPropagationPolicy *metav1.DeletionPropagation `json:"deletionPropagationPolicy,omitempty"`
// Cluster defines the target cluster (will be inherited if not specified).
// +optional
Cluster *string `json:"cluster,omitempty"`
// Clusters holds a registry to clusters to support multi-cluster tests.
// +optional
Clusters Clusters `json:"clusters,omitempty"`
// SkipDelete determines whether the resources created by the step should be deleted after the test step is executed.
// +optional
SkipDelete *bool `json:"skipDelete,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// Compiler defines the default compiler to use when evaluating expressions.
// +optional
Compiler *Compiler `json:"compiler,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Try defines what the step will try to execute.
// +kubebuilder:validation:MinItems:=1
// +optional
Try []Operation `json:"try"`
// Catch defines what the step will execute when an error happens.
// +optional
Catch []CatchFinally `json:"catch,omitempty"`
// Finally defines what the step will execute after the step is terminated.
// +optional
Finally []CatchFinally `json:"finally,omitempty"`
// Cleanup defines what will be executed after the test is terminated.
// +optional
Cleanup []CatchFinally `json:"cleanup,omitempty"`
}

View File

@ -8,7 +8,6 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true // +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster // +kubebuilder:resource:scope=Cluster
// +kubebuilder:storageversion
// Test is the resource that contains a test definition. // Test is the resource that contains a test definition.
type Test struct { type Test struct {
@ -21,96 +20,3 @@ type Test struct {
// Test spec. // Test spec.
Spec TestSpec `json:"spec"` Spec TestSpec `json:"spec"`
} }
// TestSpec contains the test spec.
type TestSpec struct {
// Description contains a description of the test.
// +optional
Description string `json:"description,omitempty"`
// FailFast determines whether the test should stop upon encountering the first failure.
// +optional
FailFast *bool `json:"failFast,omitempty"`
// Timeouts for the test. Overrides the global timeouts set in the Configuration on a per operation basis.
// +optional
Timeouts *Timeouts `json:"timeouts,omitempty"`
// Cluster defines the target cluster (will be inherited if not specified).
// +optional
Cluster *string `json:"cluster,omitempty"`
// Clusters holds a registry to clusters to support multi-cluster tests.
// +optional
Clusters Clusters `json:"clusters,omitempty"`
// Skip determines whether the test should skipped.
// +optional
Skip *bool `json:"skip,omitempty"`
// Concurrent determines whether the test should run concurrently with other tests.
// +optional
Concurrent *bool `json:"concurrent,omitempty"`
// SkipDelete determines whether the resources created by the test should be deleted after the test is executed.
// +optional
SkipDelete *bool `json:"skipDelete,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// Compiler defines the default compiler to use when evaluating expressions.
// +optional
Compiler *Compiler `json:"compiler,omitempty"`
// Namespace determines whether the test should run in a random ephemeral namespace or not.
// +optional
Namespace string `json:"namespace,omitempty"`
// NamespaceTemplate defines a template to create the test namespace.
// +optional
NamespaceTemplate *Projection `json:"namespaceTemplate,omitempty"`
// NamespaceTemplateCompiler defines the default compiler to use when evaluating expressions.
// +optional
NamespaceTemplateCompiler *Compiler `json:"namespaceTemplateCompiler,omitempty"`
// Scenarios defines test scenarios.
// +optional
Scenarios []Scenario `json:"scenarios,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Steps defining the test.
Steps []TestStep `json:"steps"`
// Catch defines what the steps will execute when an error happens.
// This will be combined with catch handlers defined at the step level.
// +optional
Catch []CatchFinally `json:"catch,omitempty"`
// ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.
// +optional
ForceTerminationGracePeriod *metav1.Duration `json:"forceTerminationGracePeriod,omitempty"`
// DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.
// +optional
DelayBeforeCleanup *metav1.Duration `json:"delayBeforeCleanup,omitempty"`
// DeletionPropagationPolicy decides if a deletion will propagate to the dependents of
// the object, and how the garbage collector will handle the propagation.
// Overrides the deletion propagation policy set in the Configuration.
// +optional
// +kubebuilder:validation:Enum:=Orphan;Background;Foreground
DeletionPropagationPolicy *metav1.DeletionPropagation `json:"deletionPropagationPolicy,omitempty"`
}
// Scenario defines per scenario bindings.
type Scenario struct {
// Bindings defines binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
}

View File

@ -0,0 +1,64 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// TestSpec contains the test spec.
type TestSpec struct {
// Description contains a description of the test.
// +optional
Description string `json:"description,omitempty"`
// Timeouts for the test. Overrides the global timeouts set in the Configuration on a per operation basis.
// +optional
Timeouts *Timeouts `json:"timeouts,omitempty"`
// Cluster defines the target cluster (default cluster will be used if not specified and/or overridden).
// +optional
Cluster string `json:"cluster,omitempty"`
// Skip determines whether the test should skipped.
// +optional
Skip *bool `json:"skip,omitempty"`
// Concurrent determines whether the test should run concurrently with other tests.
// +optional
Concurrent *bool `json:"concurrent,omitempty"`
// SkipDelete determines whether the resources created by the test should be deleted after the test is executed.
// +optional
SkipDelete *bool `json:"skipDelete,omitempty"`
// Template determines whether resources should be considered for templating.
// +optional
Template *bool `json:"template,omitempty"`
// Namespace determines whether the test should run in a random ephemeral namespace or not.
// +optional
Namespace string `json:"namespace,omitempty"`
// NamespaceTemplate defines a template to create the test namespace.
// +optional
NamespaceTemplate *Any `json:"namespaceTemplate,omitempty"`
// Bindings defines additional binding key/values.
// +optional
Bindings []Binding `json:"bindings,omitempty"`
// Steps defining the test.
Steps []TestSpecStep `json:"steps"`
// Catch defines what the steps will execute when an error happens.
// This will be combined with catch handlers defined at the step level.
// +optional
Catch []Catch `json:"catch,omitempty"`
// ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.
// +optional
ForceTerminationGracePeriod *metav1.Duration `json:"forceTerminationGracePeriod,omitempty"`
// DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.
// +optional
DelayBeforeCleanup *metav1.Duration `json:"delayBeforeCleanup,omitempty"`
}

View File

@ -0,0 +1,11 @@
package v1alpha1
// TestSpecStep contains the test step definition used in a test spec.
type TestSpecStep struct {
// Name of the step.
// +optional
Name string `json:"name,omitempty"`
// TestStepSpec of the step.
TestStepSpec `json:",inline"`
}

View File

@ -0,0 +1,22 @@
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
// TestStep is the resource that contains the testStep used to run tests.
type TestStep struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// TestStep spec.
Spec TestStepSpec `json:"spec"`
}

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