├── .assets
├── kyverno-chainsaw-horizontal.png
├── kyverno-chainsaw-logo.png
└── kyverno-chainsaw-logo.pptx
├── .crds
├── chainsaw.kyverno.io_configurations.yaml
├── chainsaw.kyverno.io_steptemplates.yaml
└── chainsaw.kyverno.io_tests.yaml
├── .docs
├── LABELS.md
└── RELEASE.md
├── .github
├── ISSUE_TEMPLATE
│ ├── bug.yaml
│ ├── config.yml
│ ├── feature-request.yaml
│ └── general-question.yaml
├── PULL_REQUEST_TEMPLATE.md
├── cherry-pick-bot.yml
├── dependabot.yml
└── workflows
│ ├── check-actions.yaml
│ ├── check-milestone.yaml
│ ├── codegen.yaml
│ ├── codeql.yaml
│ ├── docs-main.yaml
│ ├── docs-release.yaml
│ ├── lint.yaml
│ ├── pr-semantics.yaml
│ ├── release.yaml
│ └── tests.yaml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yaml
├── .ko.yaml
├── .release-notes
├── _template.md
├── main.md
├── v0.0.1.md
├── v0.0.2.md
├── v0.0.3.md
├── v0.0.4.md
├── v0.0.5.md
├── v0.0.6.md
├── v0.0.7.md
├── v0.0.8.md
├── v0.0.9.md
├── v0.1.0.md
├── v0.1.1.md
├── v0.1.2.md
├── v0.1.3.md
├── v0.1.4.md
├── v0.1.5.md
├── v0.1.6.md
├── v0.1.7.md
├── v0.1.8.md
├── v0.1.9.md
├── v0.2.0.md
├── v0.2.1.md
├── v0.2.10.md
├── v0.2.11.md
├── v0.2.12.md
├── v0.2.2.md
├── v0.2.3.md
├── v0.2.4.md
├── v0.2.5.md
├── v0.2.6.md
├── v0.2.7.md
├── v0.2.8.md
└── v0.2.9.md
├── .schemas
└── json
│ ├── configuration-chainsaw-v1alpha1.json
│ ├── configuration-chainsaw-v1alpha2.json
│ ├── steptemplate-chainsaw-v1alpha1.json
│ └── test-chainsaw-v1alpha1.json
├── .vscode
└── launch.json
├── ADOPTERS.md
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── README.md
├── ROADMAP.md
├── chainsaw.rb
├── codecov.yml
├── go.mod
├── go.sum
├── hack
├── boilerplate.go.txt
└── controller-gen
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ └── markers.go
├── main.go
├── pkg
├── apis
│ ├── compiler.go
│ ├── conversion
│ │ ├── configuration.go
│ │ └── install.go
│ ├── doc.go
│ ├── v1alpha1
│ │ ├── action.go
│ │ ├── catch_finally.go
│ │ ├── catch_finally_test.go
│ │ ├── configuration.go
│ │ ├── doc.go
│ │ ├── operation.go
│ │ ├── operation_test.go
│ │ ├── projection.go
│ │ ├── step.go
│ │ ├── test.go
│ │ ├── types.go
│ │ ├── types_test.go
│ │ ├── zz_generated.deepcopy.go
│ │ └── zz_generated.register.go
│ └── v1alpha2
│ │ ├── configuration.go
│ │ ├── doc.go
│ │ ├── options.go
│ │ ├── types.go
│ │ ├── zz_generated.deepcopy.go
│ │ └── zz_generated.register.go
├── cleanup
│ └── cleaner
│ │ ├── cleaner.go
│ │ └── cleaner_test.go
├── client
│ ├── client.go
│ ├── dryrun
│ │ ├── dry_run.go
│ │ └── dry_run_test.go
│ ├── simple
│ │ ├── auth.go
│ │ ├── client.go
│ │ └── client_test.go
│ ├── testing
│ │ └── fake_client.go
│ ├── types.go
│ ├── utils.go
│ └── utils_test.go
├── commands
│ ├── assert
│ │ ├── command.go
│ │ └── command_test.go
│ ├── build
│ │ ├── command.go
│ │ ├── command_test.go
│ │ └── docs
│ │ │ ├── catalog.tmpl
│ │ │ ├── command.go
│ │ │ ├── command_test.go
│ │ │ └── docs.tmpl
│ ├── create
│ │ ├── command.go
│ │ ├── command_test.go
│ │ └── test
│ │ │ ├── command.go
│ │ │ └── command_test.go
│ ├── docs
│ │ ├── command.go
│ │ ├── command_test.go
│ │ ├── options.go
│ │ ├── options_test.go
│ │ └── utils.go
│ ├── export
│ │ ├── command.go
│ │ ├── command_test.go
│ │ └── schemas
│ │ │ ├── command.go
│ │ │ └── command_test.go
│ ├── lint
│ │ ├── command.go
│ │ ├── command_test.go
│ │ ├── processor.go
│ │ └── schema.go
│ ├── migrate
│ │ ├── command.go
│ │ ├── command_test.go
│ │ └── kuttl
│ │ │ ├── command.go
│ │ │ ├── command_test.go
│ │ │ ├── config
│ │ │ ├── command.go
│ │ │ └── command_test.go
│ │ │ └── tests
│ │ │ ├── command.go
│ │ │ └── command_test.go
│ ├── renovate
│ │ ├── command.go
│ │ ├── command_test.go
│ │ └── config
│ │ │ ├── command.go
│ │ │ └── command_test.go
│ ├── root.go
│ ├── root
│ │ ├── command.go
│ │ └── command_test.go
│ ├── root_test.go
│ ├── test
│ │ ├── command.go
│ │ └── command_test.go
│ └── version
│ │ ├── command.go
│ │ └── command_test.go
├── data
│ ├── config
│ │ └── default.yaml
│ ├── crds
│ │ ├── chainsaw.kyverno.io_configurations.yaml
│ │ ├── chainsaw.kyverno.io_steptemplates.yaml
│ │ └── chainsaw.kyverno.io_tests.yaml
│ ├── data.go
│ ├── data_test.go
│ └── schemas
│ │ └── json
│ │ ├── configuration-chainsaw-v1alpha1.json
│ │ ├── configuration-chainsaw-v1alpha2.json
│ │ ├── steptemplate-chainsaw-v1alpha1.json
│ │ └── test-chainsaw-v1alpha1.json
├── discovery
│ ├── discovery.go
│ ├── discovery_test.go
│ ├── load.go
│ ├── load_test.go
│ ├── step.go
│ └── test.go
├── engine
│ ├── bindings
│ │ ├── bindings.go
│ │ └── bindings_test.go
│ ├── checks
│ │ ├── check.go
│ │ ├── check_test.go
│ │ ├── expect.go
│ │ └── expect_test.go
│ ├── client
│ │ ├── client.go
│ │ └── client_test.go
│ ├── clusters
│ │ ├── cluster.go
│ │ ├── cluster_test.go
│ │ ├── registry.go
│ │ └── registry_test.go
│ ├── functions
│ │ ├── caller.go
│ │ ├── env.go
│ │ ├── env_test.go
│ │ ├── functions.go
│ │ ├── functions_test.go
│ │ ├── k8s.go
│ │ ├── k8s_test.go
│ │ ├── metrics.go
│ │ ├── strings.go
│ │ └── utils.go
│ ├── kubectl
│ │ ├── describe.go
│ │ ├── describe_test.go
│ │ ├── get.go
│ │ ├── get_test.go
│ │ ├── logs.go
│ │ ├── logs_test.go
│ │ ├── mapping.go
│ │ ├── proxy.go
│ │ ├── proxy_test.go
│ │ ├── wait.go
│ │ └── wait_test.go
│ ├── namespacer
│ │ ├── namespacer.go
│ │ ├── namespacer_test.go
│ │ └── testing
│ │ │ └── fake_namespacer.go
│ ├── operations
│ │ ├── apply
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── assert
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── command
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── create
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── delete
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── error
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── errors
│ │ │ └── resource.go
│ │ ├── internal
│ │ │ ├── command_output.go
│ │ │ ├── command_output_test.go
│ │ │ ├── env.go
│ │ │ ├── log.go
│ │ │ ├── log_test.go
│ │ │ ├── namespace.go
│ │ │ ├── namespace_test.go
│ │ │ ├── read.go
│ │ │ └── read_test.go
│ │ ├── operation.go
│ │ ├── patch
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── script
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── sleep
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ │ ├── testing
│ │ │ └── mock.go
│ │ └── update
│ │ │ ├── operation.go
│ │ │ └── operation_test.go
│ ├── outputs
│ │ ├── outputs.go
│ │ └── outputs_test.go
│ ├── templating
│ │ ├── convert.go
│ │ ├── convert_test.go
│ │ ├── resource_ref.go
│ │ ├── resource_ref_test.go
│ │ ├── template.go
│ │ └── template_test.go
│ └── types.go
├── expressions
│ ├── parse.go
│ ├── string.go
│ ├── string_pointer.go
│ ├── string_pointer_test.go
│ └── string_test.go
├── loaders
│ ├── config
│ │ ├── default.go
│ │ ├── default_test.go
│ │ ├── load.go
│ │ └── load_test.go
│ ├── default.go
│ ├── default_test.go
│ ├── resource
│ │ ├── load.go
│ │ └── load_test.go
│ ├── steptemplate
│ │ ├── load.go
│ │ └── load_test.go
│ ├── test
│ │ ├── load.go
│ │ └── load_test.go
│ ├── testing
│ │ └── fake_loader.go
│ └── values
│ │ ├── load.go
│ │ └── load_test.go
├── logging
│ ├── context.go
│ ├── context_test.go
│ ├── log.go
│ ├── log_test.go
│ ├── logger.go
│ ├── logger_test.go
│ ├── operation.go
│ ├── section.go
│ ├── section_test.go
│ ├── sink.go
│ ├── sink_test.go
│ └── status.go
├── metrics
│ └── decode.go
├── mocks
│ └── logger.go
├── model
│ ├── config.go
│ ├── report.go
│ ├── report_test.go
│ ├── summary.go
│ ├── summary_test.go
│ └── test.go
├── mutate
│ ├── expression.go
│ ├── mutate.go
│ ├── mutate_test.go
│ ├── mutation.go
│ └── parse.go
├── report
│ ├── json.go
│ ├── junit.go
│ ├── report.go
│ └── report_test.go
├── runner
│ ├── context
│ │ ├── context.go
│ │ ├── context_test.go
│ │ ├── helpers.go
│ │ ├── init.go
│ │ ├── init_test.go
│ │ └── legacy.go
│ ├── flags
│ │ ├── flags.go
│ │ └── flags_test.go
│ ├── info.go
│ ├── internal
│ │ ├── corpus_entry.go
│ │ ├── test_deps.go
│ │ └── test_deps_test.go
│ ├── main_start.go
│ ├── mocks
│ │ └── registry.go
│ ├── names
│ │ ├── step.go
│ │ ├── step_test.go
│ │ ├── test.go
│ │ └── test_test.go
│ ├── namespace.go
│ ├── namespace_test.go
│ ├── operations
│ │ ├── apply.go
│ │ ├── assert.go
│ │ ├── command.go
│ │ ├── create.go
│ │ ├── delete.go
│ │ ├── describe.go
│ │ ├── error.go
│ │ ├── factory.go
│ │ ├── get.go
│ │ ├── helpers.go
│ │ ├── operation.go
│ │ ├── patch.go
│ │ ├── podlogs.go
│ │ ├── proxy.go
│ │ ├── script.go
│ │ ├── sleep.go
│ │ ├── sleep_test.go
│ │ ├── update.go
│ │ ├── wait.go
│ │ └── wait_test.go
│ ├── runner.go
│ ├── runner_test.go
│ ├── sink.go
│ ├── sink_test.go
│ └── step_test.go
├── utils
│ ├── diff
│ │ ├── diff.go
│ │ └── diff_test.go
│ ├── env
│ │ ├── expand.go
│ │ └── expand_test.go
│ ├── flag
│ │ ├── flag.go
│ │ └── flag_test.go
│ ├── fs
│ │ ├── check.go
│ │ ├── check_test.go
│ │ ├── discover.go
│ │ └── discover_test.go
│ ├── kube
│ │ ├── namespace.go
│ │ ├── namespace_test.go
│ │ ├── unstructured.go
│ │ └── unstructured_test.go
│ ├── maps
│ │ ├── merge.go
│ │ └── merge_test.go
│ ├── rest
│ │ ├── config.go
│ │ └── config_test.go
│ └── yaml
│ │ ├── with-anchors.yaml
│ │ ├── without-anchors.yaml
│ │ ├── yaml.go
│ │ └── yaml_test.go
└── version
│ ├── version.go
│ └── version_test.go
├── requirements.txt
├── testdata
├── .kube
│ └── config
├── commands
│ ├── assert
│ │ ├── assert.yaml
│ │ └── help.txt
│ ├── build
│ │ ├── docs
│ │ │ └── help.txt
│ │ └── help.txt
│ ├── create
│ │ ├── help.txt
│ │ └── test
│ │ │ ├── help.txt
│ │ │ └── out.txt
│ ├── docs
│ │ ├── help.txt
│ │ └── invalid-output.txt
│ ├── export
│ │ ├── help.txt
│ │ └── schemas
│ │ │ └── help.txt
│ ├── help.txt
│ ├── lint
│ │ ├── configuration
│ │ │ ├── configuration.json
│ │ │ ├── configuration.yaml
│ │ │ ├── pass.txt
│ │ │ ├── wrong-configuration.json
│ │ │ └── wrong-configuration.yaml
│ │ └── test
│ │ │ ├── pass.txt
│ │ │ ├── test.json
│ │ │ ├── test.yaml
│ │ │ ├── txt.txt
│ │ │ ├── wrong-test.json
│ │ │ └── wrong-test.yaml
│ ├── migrate
│ │ ├── help.txt
│ │ └── kuttl
│ │ │ ├── config
│ │ │ ├── help.txt
│ │ │ ├── out-save.txt
│ │ │ └── out.txt
│ │ │ ├── help.txt
│ │ │ └── tests
│ │ │ ├── help.txt
│ │ │ ├── out-save.txt
│ │ │ └── out.txt
│ ├── renovate
│ │ ├── config
│ │ │ ├── help.txt
│ │ │ ├── out-save.txt
│ │ │ ├── v1alpha1-custom.txt
│ │ │ └── v1alpha1-default.txt
│ │ └── help.txt
│ ├── root
│ │ └── help.txt
│ ├── test
│ │ ├── all_flags.txt
│ │ ├── config
│ │ │ ├── config_all_fields.yaml
│ │ │ ├── empty_config.yaml
│ │ │ ├── wrong_format_config.yaml
│ │ │ └── wrong_kind_config.yaml
│ │ ├── config_all_fields.txt
│ │ ├── default.txt
│ │ ├── help.txt
│ │ ├── with_regex.txt
│ │ ├── with_repeat_count.txt
│ │ ├── with_suppress.txt
│ │ ├── with_test_dirs.txt
│ │ ├── with_timeout.txt
│ │ ├── wrong_format_config.txt
│ │ ├── wrong_kind_config.txt
│ │ └── wrong_kind_config_err.txt
│ └── version
│ │ ├── help.txt
│ │ └── out.txt
├── config
│ ├── configmap.yaml
│ ├── empty.yaml
│ ├── multiple.yaml
│ └── v1alpha1
│ │ ├── bad-catch.yaml
│ │ ├── custom-config.yaml
│ │ └── default.yaml
├── discovery
│ ├── empty-test
│ │ └── fake.json
│ ├── manifests
│ │ ├── 01-assert.yaml
│ │ ├── 01-configmap.yaml
│ │ └── 01-errors.yaml
│ ├── multiple-tests
│ │ └── chainsaw-test.yaml
│ ├── not-a-test
│ │ └── configmap.yaml
│ ├── test-yml
│ │ └── chainsaw-test.yml
│ └── test
│ │ └── chainsaw-test.yaml
├── e2e
│ ├── config.yaml
│ ├── examples
│ │ ├── CATALOG.md
│ │ ├── apply-outputs
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── resources.yaml
│ │ ├── array-assertion
│ │ │ ├── README.md
│ │ │ ├── assertions.yaml
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── resources.yaml
│ │ ├── assertion-tree
│ │ │ ├── README.md
│ │ │ ├── assert.yaml
│ │ │ └── chainsaw-test.yaml
│ │ ├── basic
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ ├── configmap-assert.yaml
│ │ │ └── configmap.yaml
│ │ ├── bindings
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── catch
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── cel
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── command-output
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── delete
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── cms.yaml
│ │ ├── deployment
│ │ │ ├── README.md
│ │ │ ├── assertions.yaml
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── resources.yaml
│ │ ├── dynamic-clusters
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── field-validation
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── finally
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── inline
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── jmespath-label-condition
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── k8s-server-version
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── list
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── list.yaml
│ │ ├── metrics-decode
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── namespace-template-config
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── namespace-template
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── negative-testing
│ │ │ ├── resource
│ │ │ │ ├── README.md
│ │ │ │ ├── chainsaw-test.yaml
│ │ │ │ └── resources.yaml
│ │ │ └── script
│ │ │ │ ├── README.md
│ │ │ │ └── chainsaw-test.yaml
│ │ ├── non-resource-assertion
│ │ │ ├── README.md
│ │ │ ├── assert.yaml
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── error.yaml
│ │ ├── orphan
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── outputs
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── patch
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── proxy
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── quick-start
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── configmap.yaml
│ │ ├── scenarios
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── script-env
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── sleep
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── step-template-bindings
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── template.yaml
│ │ ├── step-template
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ ├── configmap.yaml
│ │ │ └── step-template.yaml
│ │ ├── template
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── test-info
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── timeout
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yml
│ │ ├── update-crd
│ │ │ ├── README.md
│ │ │ ├── chainsaw-test.yaml
│ │ │ └── crd.yaml
│ │ ├── update
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── values
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ ├── wait
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ │ └── yaml-anchors
│ │ │ ├── README.md
│ │ │ └── chainsaw-test.yaml
│ └── values.yaml
├── kuttl
│ ├── .chainsaw.yaml
│ ├── 01-assert.yaml
│ ├── 01-step.yaml
│ ├── 02-assert.yaml
│ ├── 02-step.yaml
│ ├── configmap.yaml
│ ├── invalid-config.yaml
│ ├── kuttl-test.yaml
│ └── multiple-config.yaml
├── report
│ ├── JSON.json
│ ├── JUNIT-OPERATION.xml
│ ├── JUNIT-STEP.xml
│ ├── JUNIT-TEST.xml
│ └── XML.xml
├── resource
│ ├── custom-resource.yaml
│ ├── empty.yaml
│ ├── folder-invalid
│ │ ├── custom-resource.yaml
│ │ └── invalid.yaml
│ ├── folder-valid
│ │ ├── custom-resource.yaml
│ │ └── valid.yaml
│ ├── invalid.yaml
│ ├── list.yaml
│ └── valid.yaml
├── runner
│ └── processors
│ │ ├── cron-job.yaml
│ │ ├── deployment.yaml
│ │ └── pod.yaml
├── step-template
│ ├── bad-step.yaml
│ ├── configmap.yaml
│ ├── custom.yaml
│ ├── empty.yaml
│ ├── multiple.yaml
│ ├── no-spec.yaml
│ └── no-try.yaml
├── test
│ ├── bad-step.yaml
│ ├── configmap.yaml
│ ├── custom-test.yaml
│ ├── empty.yaml
│ ├── multiple.yaml
│ ├── no-spec.yaml
│ ├── no-steps.yaml
│ ├── ok.yaml
│ └── raw-resource.yaml
├── validation
│ └── example-file.yaml
└── values
│ ├── empty.yaml
│ ├── invalid.yaml
│ ├── values-1.yaml
│ └── values-2.yaml
└── website
├── apis
├── config.yaml
└── markdown
│ ├── members.tpl
│ ├── pkg.tpl
│ └── type.tpl
├── docs
├── cicd
│ └── gh-action.md
├── community
│ ├── contribute.md
│ ├── index.md
│ ├── making-a-pull-request.md
│ ├── reporting-a-bug.md
│ ├── reporting-a-docs-issue.md
│ └── requesting-a-change.md
├── configuration
│ ├── file.md
│ ├── flags.md
│ ├── index.md
│ └── options
│ │ ├── cleanup.md
│ │ ├── clusters.md
│ │ ├── deletion.md
│ │ ├── discovery.md
│ │ ├── error.md
│ │ ├── execution.md
│ │ ├── label-selectors.md
│ │ ├── namespace.md
│ │ ├── no-cluster.md
│ │ ├── pause.md
│ │ ├── report.md
│ │ ├── templating.md
│ │ ├── timeouts.md
│ │ └── values.md
├── examples
│ ├── concurrency.md
│ ├── crds.md
│ ├── events.md
│ ├── index.md
│ ├── inline.md
│ ├── kube-version.md
│ ├── label-selectors.md
│ ├── multi-cluster.md
│ ├── negative-testing.md
│ ├── non-resource-assertions.md
│ ├── test-output.md
│ └── values.md
├── general
│ ├── bindings.md
│ ├── checks.md
│ ├── inheritance.md
│ ├── namespace.md
│ ├── outputs.md
│ ├── references.md
│ └── templating.md
├── guides
│ ├── kuttl-migration.md
│ ├── lint.md
│ └── test-docs.md
├── index.md
├── operations
│ ├── apply.md
│ ├── assert.md
│ ├── command.md
│ ├── create.md
│ ├── delete.md
│ ├── error.md
│ ├── helpers
│ │ ├── describe.md
│ │ ├── events.md
│ │ ├── get.md
│ │ ├── index.md
│ │ ├── logs.md
│ │ └── wait.md
│ ├── index.md
│ ├── patch.md
│ ├── script.md
│ ├── sleep.md
│ ├── todo
│ │ ├── non-resource-assert._md
│ │ └── templating._md
│ └── update.md
├── overrides
│ ├── home.html
│ └── main.html
├── quick-start
│ ├── assertion-trees.md
│ ├── bindings.md
│ ├── cleanup.md
│ ├── completion.md
│ ├── first-test.md
│ ├── index.md
│ ├── install.md
│ ├── next-steps.md
│ ├── operation-outputs.md
│ ├── resource-templating.md
│ ├── resources.md
│ ├── run-tests.md
│ ├── timeouts.md
│ └── try-catch.md
├── reference
│ ├── apis
│ │ ├── chainsaw.v1alpha1.md
│ │ └── chainsaw.v1alpha2.md
│ ├── builtins.md
│ ├── commands
│ │ ├── chainsaw.md
│ │ ├── chainsaw_assert.md
│ │ ├── chainsaw_build.md
│ │ ├── chainsaw_build_docs.md
│ │ ├── chainsaw_completion.md
│ │ ├── chainsaw_completion_bash.md
│ │ ├── chainsaw_completion_fish.md
│ │ ├── chainsaw_completion_powershell.md
│ │ ├── chainsaw_completion_zsh.md
│ │ ├── chainsaw_create.md
│ │ ├── chainsaw_create_test.md
│ │ ├── chainsaw_docs.md
│ │ ├── chainsaw_export.md
│ │ ├── chainsaw_export_schemas.md
│ │ ├── chainsaw_lint.md
│ │ ├── chainsaw_migrate.md
│ │ ├── chainsaw_migrate_kuttl.md
│ │ ├── chainsaw_migrate_kuttl_config.md
│ │ ├── chainsaw_migrate_kuttl_tests.md
│ │ ├── chainsaw_renovate.md
│ │ ├── chainsaw_renovate_config.md
│ │ ├── chainsaw_test.md
│ │ └── chainsaw_version.md
│ ├── index.md
│ ├── jp
│ │ ├── examples
│ │ │ ├── abs.md
│ │ │ ├── add.md
│ │ │ ├── as_string.md
│ │ │ ├── at.md
│ │ │ ├── avg.md
│ │ │ ├── base64_decode.md
│ │ │ ├── base64_encode.md
│ │ │ ├── ceil.md
│ │ │ ├── compare.md
│ │ │ ├── concat.md
│ │ │ ├── contains.md
│ │ │ ├── divide.md
│ │ │ ├── ends_with.md
│ │ │ ├── env.md
│ │ │ ├── equal_fold.md
│ │ │ ├── find_first.md
│ │ │ ├── find_last.md
│ │ │ ├── floor.md
│ │ │ ├── from_items.md
│ │ │ ├── group_by.md
│ │ │ ├── items.md
│ │ │ ├── join.md
│ │ │ ├── json_parse.md
│ │ │ ├── keys.md
│ │ │ ├── label_match.md
│ │ │ ├── length.md
│ │ │ ├── lookup.md
│ │ │ ├── lower.md
│ │ │ ├── map.md
│ │ │ ├── max.md
│ │ │ ├── max_by.md
│ │ │ ├── merge.md
│ │ │ ├── min.md
│ │ │ ├── min_by.md
│ │ │ ├── modulo.md
│ │ │ ├── multiply.md
│ │ │ ├── not_null.md
│ │ │ ├── object_from_lists.md
│ │ │ ├── pad_left.md
│ │ │ ├── pad_right.md
│ │ │ ├── parse_json.md
│ │ │ ├── parse_yaml.md
│ │ │ ├── path_canonicalize.md
│ │ │ ├── pattern_match.md
│ │ │ ├── random.md
│ │ │ ├── regex_match.md
│ │ │ ├── regex_replace_all.md
│ │ │ ├── regex_replace_all_literal.md
│ │ │ ├── replace.md
│ │ │ ├── replace_all.md
│ │ │ ├── reverse.md
│ │ │ ├── round.md
│ │ │ ├── semver_compare.md
│ │ │ ├── sort.md
│ │ │ ├── sort_by.md
│ │ │ ├── split.md
│ │ │ ├── starts_with.md
│ │ │ ├── subtract.md
│ │ │ ├── sum.md
│ │ │ ├── time_add.md
│ │ │ ├── time_after.md
│ │ │ ├── time_before.md
│ │ │ ├── time_between.md
│ │ │ ├── time_diff.md
│ │ │ ├── time_now.md
│ │ │ ├── time_now_utc.md
│ │ │ ├── time_parse.md
│ │ │ ├── time_since.md
│ │ │ ├── time_to_cron.md
│ │ │ ├── time_truncate.md
│ │ │ ├── time_utc.md
│ │ │ ├── to_array.md
│ │ │ ├── to_boolean.md
│ │ │ ├── to_lower.md
│ │ │ ├── to_number.md
│ │ │ ├── to_string.md
│ │ │ ├── to_upper.md
│ │ │ ├── trim.md
│ │ │ ├── trim_left.md
│ │ │ ├── trim_prefix.md
│ │ │ ├── trim_right.md
│ │ │ ├── trim_space.md
│ │ │ ├── truncate.md
│ │ │ ├── type.md
│ │ │ ├── upper.md
│ │ │ ├── values.md
│ │ │ ├── wildcard.md
│ │ │ ├── x509_decode.md
│ │ │ ├── x_k8s_exists.md
│ │ │ ├── x_k8s_get.md
│ │ │ ├── x_k8s_list.md
│ │ │ ├── x_k8s_resource_exists.md
│ │ │ ├── x_k8s_server_version.md
│ │ │ ├── x_metrics_decode.md
│ │ │ └── zip.md
│ │ └── functions.md
│ └── json-schemas.md
├── static
│ ├── extra.css
│ ├── favicon.ico
│ ├── kyverno-chainsaw-horizontal.png
│ ├── kyverno-chainsaw-logo.png
│ └── repo-card.js
├── step
│ ├── catch.md
│ ├── cleanup.md
│ ├── finally.md
│ ├── index.md
│ └── try.md
└── test
│ ├── conventional.md
│ ├── explicit.md
│ ├── index.md
│ └── spec
│ └── index.md
├── jp
├── examples
│ ├── abs.md
│ ├── add.md
│ ├── as_string.md
│ ├── at.md
│ ├── avg.md
│ ├── base64_decode.md
│ ├── base64_encode.md
│ ├── ceil.md
│ ├── compare.md
│ ├── concat.md
│ ├── contains.md
│ ├── divide.md
│ ├── ends_with.md
│ ├── env.md
│ ├── equal_fold.md
│ ├── find_first.md
│ ├── find_last.md
│ ├── floor.md
│ ├── from_items.md
│ ├── group_by.md
│ ├── items.md
│ ├── join.md
│ ├── json_parse.md
│ ├── keys.md
│ ├── label_match.md
│ ├── length.md
│ ├── lookup.md
│ ├── lower.md
│ ├── map.md
│ ├── max.md
│ ├── max_by.md
│ ├── merge.md
│ ├── min.md
│ ├── min_by.md
│ ├── modulo.md
│ ├── multiply.md
│ ├── not_null.md
│ ├── object_from_lists.md
│ ├── pad_left.md
│ ├── pad_right.md
│ ├── parse_json.md
│ ├── parse_yaml.md
│ ├── path_canonicalize.md
│ ├── pattern_match.md
│ ├── random.md
│ ├── regex_match.md
│ ├── regex_replace_all.md
│ ├── regex_replace_all_literal.md
│ ├── replace.md
│ ├── replace_all.md
│ ├── reverse.md
│ ├── round.md
│ ├── semver_compare.md
│ ├── sort.md
│ ├── sort_by.md
│ ├── split.md
│ ├── starts_with.md
│ ├── subtract.md
│ ├── sum.md
│ ├── time_add.md
│ ├── time_after.md
│ ├── time_before.md
│ ├── time_between.md
│ ├── time_diff.md
│ ├── time_now.md
│ ├── time_now_utc.md
│ ├── time_parse.md
│ ├── time_since.md
│ ├── time_to_cron.md
│ ├── time_truncate.md
│ ├── time_utc.md
│ ├── to_array.md
│ ├── to_boolean.md
│ ├── to_lower.md
│ ├── to_number.md
│ ├── to_string.md
│ ├── to_upper.md
│ ├── trim.md
│ ├── trim_left.md
│ ├── trim_prefix.md
│ ├── trim_right.md
│ ├── trim_space.md
│ ├── truncate.md
│ ├── type.md
│ ├── upper.md
│ ├── values.md
│ ├── wildcard.md
│ ├── x509_decode.md
│ ├── x_k8s_exists.md
│ ├── x_k8s_get.md
│ ├── x_k8s_list.md
│ ├── x_k8s_resource_exists.md
│ ├── x_k8s_server_version.md
│ ├── x_metrics_decode.md
│ └── zip.md
└── main.go
├── mkdocs.base.yaml
└── mkdocs.yaml
/.assets/kyverno-chainsaw-horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/.assets/kyverno-chainsaw-horizontal.png
--------------------------------------------------------------------------------
/.assets/kyverno-chainsaw-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/.assets/kyverno-chainsaw-logo.png
--------------------------------------------------------------------------------
/.assets/kyverno-chainsaw-logo.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/.assets/kyverno-chainsaw-logo.pptx
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://json.schemastore.org/github-issue-config.json
2 |
3 | blank_issues_enabled: true
4 |
5 | contact_links:
6 | - name: Chainsaw discussions
7 | url: https://github.com/kyverno/chainsaw/discussions
8 | about: Please ask and answer questions related to chainsaw here.
9 | - name: Chainsaw documentation
10 | url: https://kyverno.github.io/chainsaw
11 | about: Browse chainsaw documentation here.
12 | - name: Chainsaw slack channel
13 | url: https://kubernetes.slack.com/archives/C067LUFL43U
14 | about: Please ask and answer any chainsaw usage questions here.
15 |
--------------------------------------------------------------------------------
/.github/cherry-pick-bot.yml:
--------------------------------------------------------------------------------
1 | enabled: true
2 | preservePullRequestTitle: true
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gomod
4 | directories:
5 | - /
6 | - /hack/controller-gen/
7 | schedule:
8 | interval: daily
9 | - package-ecosystem: github-actions
10 | directory: /
11 | schedule:
12 | interval: daily
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .cache/
2 | .gopath/
3 | .temp/
4 | .tools/
5 | .venv/
6 | chainsaw
7 | coverage.out
8 | website/site
9 | pkg/runner/chainsaw.xml
10 | pkg/runner/.json
11 |
--------------------------------------------------------------------------------
/.ko.yaml:
--------------------------------------------------------------------------------
1 | defaultBaseImage: cgr.dev/chainguard/kubectl:latest-dev
--------------------------------------------------------------------------------
/.release-notes/_template.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `TODO`.
4 |
5 |
22 |
--------------------------------------------------------------------------------
/.release-notes/main.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `TODO`.
4 |
5 |
22 |
23 | ## 💫 New features 💫
24 |
25 | - Continue tests when an error happens when computing the test name
--------------------------------------------------------------------------------
/.release-notes/v0.0.1.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.0.1`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Initial MVP release with support for `Apply`, `Delete`, `Assert` and `Error` operations
8 | - Supports configuration from both config file and command line flags
9 | - Full documentation available at https://kyverno.github.io/chainsaw
10 |
--------------------------------------------------------------------------------
/.release-notes/v0.0.3.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.0.3`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - We now have a [logo](https://github.com/kyverno/chainsaw/blob/main/.assets/kyverno-chainsaw-horizontal.png) :tada:
8 | - Timeouts are now managed per operation rather than per step
9 | - Added timeout support at the operation level
10 |
11 | ## 🔧 Fixes 🔧
12 |
13 | - Fixed `Exec` collectors not invoked
14 |
15 | ## 🎸 Misc 🎸
16 |
17 | - Improved error messages in a couple of places
18 |
--------------------------------------------------------------------------------
/.release-notes/v0.0.4.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.0.4`.
4 |
5 | ## ‼️ Breaking changes ‼️
6 |
7 | - Renamed flag `stop-on-first-failure` to `fail-fast`
8 | - Lots of API changes to allow more flexibility while making the syntax simpler
9 | - Commands accepting a file now expect a single file, list of files are not supported anymore
10 |
11 | ## 💫 New features 💫
12 |
13 | - Added provenance for released images
14 | - Added a GitHub action to install Chainsaw
15 | - Added a new `Create` operation
16 | - Steps changed to follow a Try / Catch / Finally model
17 |
18 | ## 🔧 Fixes 🔧
19 |
20 | - Fixed a bug where environment variables were not expanded correctly in command arguments
21 |
22 | ## 🎸 Misc 🎸
23 |
24 | - Switched to contextual logging
25 |
--------------------------------------------------------------------------------
/.release-notes/v0.0.5.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.0.5`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Support new assertion tree model :tada:
--------------------------------------------------------------------------------
/.release-notes/v0.1.0.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.1.0`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Chainsaw is now available via brew
8 | - Added support for defining multiple tests in the same test file
9 |
10 | ## 🔧 Fixes 🔧
11 |
12 | - Fixed an incorrect error message when loading a resource failed
13 |
14 | ## ✨ UI changes ✨
15 |
16 | - Show Chainsaw version in `chainsaw test` command output
17 |
18 | ## 📚 Docs 📚
19 |
20 | - Added docs about parallel execution of Tests
21 |
22 | ## 🎸 Misc 🎸
23 |
24 | - Added an ADOPTERS.md file to the repository
25 |
--------------------------------------------------------------------------------
/.release-notes/v0.1.2.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.1.2`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Added `chainsaw lint` command to lint tests
8 | - Added non-resource assertions support
9 | - Added experimental JMESPath functions prefix (`x_`)
10 | - Added JMESPath function to interact with the cluster under test
11 |
12 | ## 🔧 Fixes 🔧
13 |
14 | - Retry not working properly in `create` and `apply` operations
15 |
16 | ## 📚 Docs 📚
17 |
18 | - Added _Examples_ docs section
19 | - Added community meeting docs
20 |
21 | ## 🎸 Misc 🎸
22 |
23 | - Added pull request template
24 | - Added issue templates
25 | - GitHub action was removed from the main chainsaw repository
26 |
--------------------------------------------------------------------------------
/.release-notes/v0.1.6.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.1.6`.
4 |
5 | ## 🔧 Fixes 🔧
6 |
7 | - Fix an issue with temporary KUBECONFIG not being an absolute path
--------------------------------------------------------------------------------
/.release-notes/v0.2.1.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.1`.
4 |
5 | ## ‼️ Breaking changes ‼️
6 |
7 | - Resource templating is now enabled by default
8 |
9 | ## 💫 New features 💫
10 |
11 | - Added `--pause-on-failure` flag to pause when a test failure happens (to ease troubleshooting)
12 | - Improved cleanup management logic, alternating `catch`, `finally` and `@cleanup` per step
13 | - Added support for registering clusters dynamically, useful when a cluster is created in a test step
14 |
15 | ## 🔧 Fixes 🔧
16 |
17 | - Fixed issue with cluster incorrectly registered
18 | - Force background deletion propagation policy (useful when testing unmanaged `Job`)
19 |
--------------------------------------------------------------------------------
/.release-notes/v0.2.11.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.11`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Added CEL support everywhere (bindings, assertion trees, projection trees, outputs...)
8 | - Added test sharding support
9 |
10 | ## 🔧 Fixes 🔧
11 |
12 | - Fixed exit code when failing in root test run
13 | - Fixed `--no-cluster` flag not working
14 |
15 | ## 📚 Docs 📚
16 |
17 | - Added most JMESPath functions docs and examples
18 |
--------------------------------------------------------------------------------
/.release-notes/v0.2.12.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.12`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Registered Kubernetes CEL libs, optional types, and various other std libs
8 | - Support conditions in labels in assertion templates
9 | - Added `skipCommandOutput` support to not log the `command` and `script` being executed
10 |
11 | ## 🔧 Fixes 🔧
12 |
13 | - Allow escaping dollar sign in `command` and `script`
14 | - Fixed `chainsaw build docs` rendering invalid yaml
15 | - Fixed step template bindings registered in the wrong order
16 |
--------------------------------------------------------------------------------
/.release-notes/v0.2.5.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.5`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Add test scenarios support
8 |
9 | ## 🔧 Fixes 🔧
10 |
11 | - Fixed a potential issue with configuration defaults and marshaling
12 |
13 | ## 🎸 Misc 🎸
14 |
15 | - Improved all Python-based build operations
16 |
--------------------------------------------------------------------------------
/.release-notes/v0.2.6.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.6`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Added a `proxy` action to allow HTTP calls to in-cluster services and pods
8 | - Added `as_string` JMESPath function to convert types based on strings to bare strings
9 | - Added `x_metrics_decode` JMESPath function to decode Prometheus metrics
10 |
--------------------------------------------------------------------------------
/.release-notes/v0.2.7.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.7`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Added initial `TestTemplate` support to allow defining steps in separate files and reusing them across tests
8 | - Replaced programmatic validation with schema-based validation
9 | - Better generated JSON schemas based on OpenAPI v3 instead of v2
10 |
11 | ## 🔧 Fixes 🔧
12 |
13 | - Fixed incorrect `null` vs empty object comparison in assertion operations
14 |
15 | ## 📚 Docs 📚
16 |
17 | - Added detailed community pages to the website website
18 | - Added a CODE_OF_CONDUCT.md file in the repo
19 |
--------------------------------------------------------------------------------
/.release-notes/v0.2.9.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | Release notes for `v0.2.9`.
4 |
5 | ## 💫 New features 💫
6 |
7 | - Added support for templating filenames used in operations
8 | - Added `ppc64le` and `s390x` binaries in release artifacts
9 | - Added support for Kubernetes 1.31
10 | - Added server side validation to validate the submitted resource
11 | - Added support for overriding the working directory in `command` and `script` operations
12 | - Compile string expressions at loading time
13 | - Made json path value optional in `wait` operation
14 | - Improved logging with `begin`, `end` and `warning` statuses
15 | - Added golang 1.23 support
16 |
17 | ## 🔧 Fixes 🔧
18 |
19 | - Fixed configuration `v1alpha2` lint command
20 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @kyverno/chainsaw-maintainers
2 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | ignore:
2 | - 'hack/**/*.go'
3 | - 'website/**/*.go'
4 | - 'pkg/apis/**/zz_*.go'
5 | - 'pkg/testing/*.go'
6 | - '**/*_test.go'
7 |
--------------------------------------------------------------------------------
/hack/boilerplate.go.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright The Kubernetes Authors.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/go-logr/logr"
7 | "github.com/kyverno/chainsaw/pkg/commands"
8 | "sigs.k8s.io/controller-runtime/pkg/log"
9 | )
10 |
11 | func main() {
12 | log.SetLogger(logr.Discard())
13 | root := commands.RootCommand()
14 | if err := root.Execute(); err != nil {
15 | os.Exit(1)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/apis/doc.go:
--------------------------------------------------------------------------------
1 | package apis
2 |
--------------------------------------------------------------------------------
/pkg/apis/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | // Package v1alpha1 contains API Schema definitions for the v1alpha1 API group.
2 | // +k8s:deepcopy-gen=package
3 | // +kubebuilder:object:generate=true
4 | // +groupName=chainsaw.kyverno.io
5 | package v1alpha1
6 |
--------------------------------------------------------------------------------
/pkg/apis/v1alpha2/doc.go:
--------------------------------------------------------------------------------
1 | // Package v1alpha2 contains API Schema definitions for the v1alpha2 API group.
2 | // +k8s:deepcopy-gen=package
3 | // +kubebuilder:object:generate=true
4 | // +groupName=chainsaw.kyverno.io
5 | package v1alpha2
6 |
--------------------------------------------------------------------------------
/pkg/apis/v1alpha2/types.go:
--------------------------------------------------------------------------------
1 | package v1alpha2
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
5 | _ "github.com/kyverno/kyverno-json/pkg/apis/policy/v1alpha1"
6 | )
7 |
8 | const (
9 | EngineJP = v1alpha1.EngineJP
10 | EngineCEL = v1alpha1.EngineCEL
11 | )
12 |
13 | type (
14 | Clusters = v1alpha1.Clusters
15 | Compiler = v1alpha1.Compiler
16 | DefaultTimeouts = v1alpha1.DefaultTimeouts
17 | Projection = v1alpha1.Projection
18 | )
19 |
--------------------------------------------------------------------------------
/pkg/client/simple/auth.go:
--------------------------------------------------------------------------------
1 | package simple
2 |
3 | import (
4 | _ "k8s.io/client-go/plugin/pkg/client/auth" // package needed for auth providers like GCP
5 | )
6 |
--------------------------------------------------------------------------------
/pkg/client/simple/client.go:
--------------------------------------------------------------------------------
1 | package simple
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/client"
5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6 | "k8s.io/client-go/rest"
7 | ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
8 | )
9 |
10 | func New(cfg *rest.Config) (client.Client, error) {
11 | var opts ctrlclient.Options
12 | client, err := ctrlclient.New(cfg, opts)
13 | if err != nil {
14 | return nil, err
15 | }
16 | return ctrlclient.WithFieldValidation(client, metav1.FieldValidationStrict), nil
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/commands/build/command.go:
--------------------------------------------------------------------------------
1 | package build
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/commands/build/docs"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func Command() *cobra.Command {
9 | cmd := &cobra.Command{
10 | Use: "build",
11 | Short: "Build commands",
12 | Args: cobra.NoArgs,
13 | SilenceUsage: true,
14 | RunE: func(cmd *cobra.Command, _ []string) error {
15 | return cmd.Help()
16 | },
17 | }
18 | cmd.AddCommand(
19 | docs.Command(),
20 | )
21 | return cmd
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/commands/build/docs/catalog.tmpl:
--------------------------------------------------------------------------------
1 | # Tests catalog
2 | {{ range .Tests }}
3 | - [{{ .Test.Name }}]({{ fpRel $.BasePath (fpJoin .BasePath $.Readme) }})
4 | {{- end }}
5 |
--------------------------------------------------------------------------------
/pkg/commands/create/command.go:
--------------------------------------------------------------------------------
1 | package create
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/commands/create/test"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func Command() *cobra.Command {
9 | cmd := &cobra.Command{
10 | Use: "create",
11 | Short: "Create Chainsaw resources",
12 | Args: cobra.NoArgs,
13 | SilenceUsage: true,
14 | RunE: func(cmd *cobra.Command, _ []string) error {
15 | return cmd.Help()
16 | },
17 | }
18 | cmd.AddCommand(
19 | test.Command(),
20 | )
21 | return cmd
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/commands/docs/utils.go:
--------------------------------------------------------------------------------
1 | package docs
2 |
3 | import (
4 | "fmt"
5 | "path"
6 | "path/filepath"
7 | "strings"
8 | "time"
9 | )
10 |
11 | const fmTemplate = `---
12 | date: %s
13 | title: "%s"
14 | weight: 35
15 | ---
16 | `
17 |
18 | func websitePrepender(filename string) string {
19 | now := time.Now().Format(time.RFC3339)
20 | name := filepath.Base(filename)
21 | base := strings.TrimSuffix(name, path.Ext(name))
22 | return fmt.Sprintf(fmTemplate, now, strings.Replace(base, "_", " ", -1))
23 | }
24 |
25 | func websiteLinkHandler(filename string) string {
26 | return "../" + strings.TrimSuffix(filename, filepath.Ext(filename))
27 | }
28 |
29 | func identity(s string) string {
30 | return s
31 | }
32 |
33 | func empty(s string) string {
34 | return ""
35 | }
36 |
--------------------------------------------------------------------------------
/pkg/commands/export/command.go:
--------------------------------------------------------------------------------
1 | package export
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/commands/export/schemas"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func Command() *cobra.Command {
9 | cmd := &cobra.Command{
10 | Use: "export",
11 | Short: "Export commands",
12 | Args: cobra.NoArgs,
13 | SilenceUsage: true,
14 | RunE: func(cmd *cobra.Command, _ []string) error {
15 | return cmd.Help()
16 | },
17 | }
18 | cmd.AddCommand(
19 | schemas.Command(),
20 | )
21 | return cmd
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/commands/lint/schema.go:
--------------------------------------------------------------------------------
1 | package lint
2 |
3 | import (
4 | "fmt"
5 | "io/fs"
6 |
7 | "github.com/kyverno/chainsaw/pkg/data"
8 | )
9 |
10 | func getScheme(kind string, version string) ([]byte, error) {
11 | schemasFs, err := data.Schemas()
12 | if err != nil {
13 | return nil, err
14 | }
15 | return fs.ReadFile(schemasFs, fmt.Sprintf("%s-chainsaw-%s.json", kind, version))
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/commands/migrate/command.go:
--------------------------------------------------------------------------------
1 | package migrate
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/commands/migrate/kuttl"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func Command() *cobra.Command {
9 | cmd := &cobra.Command{
10 | Use: "migrate",
11 | Short: "Migrate resources to Chainsaw",
12 | Args: cobra.NoArgs,
13 | SilenceUsage: true,
14 | RunE: func(cmd *cobra.Command, _ []string) error {
15 | return cmd.Help()
16 | },
17 | }
18 | cmd.AddCommand(
19 | kuttl.Command(),
20 | )
21 | return cmd
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/commands/migrate/kuttl/command.go:
--------------------------------------------------------------------------------
1 | package kuttl
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/commands/migrate/kuttl/config"
5 | "github.com/kyverno/chainsaw/pkg/commands/migrate/kuttl/tests"
6 | "github.com/spf13/cobra"
7 | )
8 |
9 | func Command() *cobra.Command {
10 | cmd := &cobra.Command{
11 | Use: "kuttl",
12 | Short: "Migrate KUTTL resources to Chainsaw",
13 | Args: cobra.NoArgs,
14 | SilenceUsage: true,
15 | RunE: func(cmd *cobra.Command, _ []string) error {
16 | return cmd.Help()
17 | },
18 | }
19 | cmd.AddCommand(
20 | config.Command(),
21 | tests.Command(),
22 | )
23 | return cmd
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/commands/renovate/command.go:
--------------------------------------------------------------------------------
1 | package renovate
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/commands/renovate/config"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func Command() *cobra.Command {
9 | cmd := &cobra.Command{
10 | Use: "renovate",
11 | Short: "Upgrade Chainsaw resources",
12 | Args: cobra.NoArgs,
13 | SilenceUsage: true,
14 | RunE: func(cmd *cobra.Command, _ []string) error {
15 | return cmd.Help()
16 | },
17 | }
18 | cmd.AddCommand(
19 | config.Command(),
20 | )
21 | return cmd
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/commands/root/command.go:
--------------------------------------------------------------------------------
1 | package root
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 | )
6 |
7 | func Command() *cobra.Command {
8 | return &cobra.Command{
9 | Use: "chainsaw",
10 | Short: "Stronger tool for e2e testing",
11 | SilenceUsage: true,
12 | RunE: func(cmd *cobra.Command, _ []string) error {
13 | return cmd.Help()
14 | },
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/commands/version/command.go:
--------------------------------------------------------------------------------
1 | package version
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/kyverno/chainsaw/pkg/version"
7 | "github.com/spf13/cobra"
8 | )
9 |
10 | func Command() *cobra.Command {
11 | return &cobra.Command{
12 | Use: "version",
13 | Short: "Print the version informations",
14 | Args: cobra.NoArgs,
15 | SilenceUsage: true,
16 | RunE: func(cmd *cobra.Command, _ []string) error {
17 | fmt.Fprintf(cmd.OutOrStdout(), "Version: %s\n", version.Version())
18 | fmt.Fprintf(cmd.OutOrStdout(), "Time: %s\n", version.Time())
19 | fmt.Fprintf(cmd.OutOrStdout(), "Git commit ID: %s\n", version.Hash())
20 | return nil
21 | },
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/pkg/data/config/default.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha2
2 | kind: Configuration
3 | metadata:
4 | name: default
5 | spec: {}
6 |
--------------------------------------------------------------------------------
/pkg/discovery/test.go:
--------------------------------------------------------------------------------
1 | package discovery
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/model"
5 | )
6 |
7 | type Test struct {
8 | Test *model.Test
9 | BasePath string
10 | Err error
11 | }
12 |
--------------------------------------------------------------------------------
/pkg/engine/functions/caller.go:
--------------------------------------------------------------------------------
1 | package functions
2 |
3 | import (
4 | "context"
5 | "sync"
6 |
7 | jpfunctions "github.com/jmespath-community/go-jmespath/pkg/functions"
8 | "github.com/jmespath-community/go-jmespath/pkg/interpreter"
9 | "github.com/kyverno/kyverno-json/pkg/jp"
10 | )
11 |
12 | var Caller = sync.OnceValue(func() interpreter.FunctionCaller {
13 | var funcs []jpfunctions.FunctionEntry
14 | funcs = append(funcs, jp.GetFunctions(context.Background())...)
15 | funcs = append(funcs, GetFunctions()...)
16 | return interpreter.NewFunctionCaller(funcs...)
17 | })
18 |
--------------------------------------------------------------------------------
/pkg/engine/functions/env.go:
--------------------------------------------------------------------------------
1 | package functions
2 |
3 | import (
4 | "os"
5 | )
6 |
7 | func jpEnv(arguments []any) (any, error) {
8 | var key string
9 | if err := getArg(arguments, 0, &key); err != nil {
10 | return nil, err
11 | }
12 | return os.Getenv(key), nil
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/engine/functions/functions_test.go:
--------------------------------------------------------------------------------
1 | package functions
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestGetFunctions(t *testing.T) {
10 | assert.Equal(t, 9, len(GetFunctions()))
11 | }
12 |
--------------------------------------------------------------------------------
/pkg/engine/functions/metrics.go:
--------------------------------------------------------------------------------
1 | package functions
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/metrics"
5 | "github.com/prometheus/common/model"
6 | )
7 |
8 | func jpMetricsDecode(arguments []any) (any, error) {
9 | var text string
10 | if err := getArg(arguments, 0, &text); err != nil {
11 | return nil, err
12 | }
13 | vector, err := metrics.Decode(text, model.Now())
14 | if err != nil {
15 | return nil, err
16 | }
17 | return vector, nil
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/engine/functions/strings.go:
--------------------------------------------------------------------------------
1 | package functions
2 |
3 | import (
4 | "strings"
5 | )
6 |
7 | func jpTrimSpace(arguments []any) (any, error) {
8 | var in string
9 | if err := getArg(arguments, 0, &in); err != nil {
10 | return nil, err
11 | }
12 | return strings.TrimSpace(in), nil
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/engine/namespacer/testing/fake_namespacer.go:
--------------------------------------------------------------------------------
1 | package testing
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/client"
5 | )
6 |
7 | type FakeNamespacer struct {
8 | ApplyFn func(call int, client client.Client, obj client.Object) error
9 | GetNamespaceFn func(call int) string
10 | numCalls int
11 | }
12 |
13 | func (n *FakeNamespacer) Apply(client client.Client, obj client.Object) error {
14 | defer func() { n.numCalls++ }()
15 | return n.ApplyFn(n.numCalls, client, obj)
16 | }
17 |
18 | func (n *FakeNamespacer) GetNamespace() string {
19 | defer func() { n.numCalls++ }()
20 | return n.GetNamespaceFn(n.numCalls)
21 | }
22 |
--------------------------------------------------------------------------------
/pkg/engine/operations/internal/log.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | "github.com/kyverno/chainsaw/pkg/client"
8 | "github.com/kyverno/chainsaw/pkg/logging"
9 | "github.com/kyverno/pkg/ext/output/color"
10 | )
11 |
12 | func LogStart(ctx context.Context, op logging.Operation, obj client.Object, args ...fmt.Stringer) {
13 | logging.Log(ctx, op, logging.RunStatus, obj, color.BoldFgCyan, args...)
14 | }
15 |
16 | func LogEnd(ctx context.Context, op logging.Operation, obj client.Object, err error) {
17 | if err != nil {
18 | logging.Log(ctx, op, logging.ErrorStatus, obj, color.BoldRed, logging.ErrSection(err))
19 | } else {
20 | logging.Log(ctx, op, logging.DoneStatus, obj, color.BoldGreen)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/engine/operations/internal/namespace.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/client"
5 | "github.com/kyverno/chainsaw/pkg/engine/namespacer"
6 | )
7 |
8 | func ApplyNamespacer(namespacer namespacer.Namespacer, client client.Client, obj client.Object) error {
9 | if namespacer == nil {
10 | return nil
11 | }
12 | return namespacer.Apply(client, obj)
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/engine/operations/operation.go:
--------------------------------------------------------------------------------
1 | package operations
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis"
7 | "github.com/kyverno/chainsaw/pkg/engine/outputs"
8 | )
9 |
10 | type Operation interface {
11 | Exec(context.Context, apis.Bindings) (outputs.Outputs, error)
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/engine/operations/testing/mock.go:
--------------------------------------------------------------------------------
1 | package testing
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis"
7 | "github.com/kyverno/chainsaw/pkg/engine/outputs"
8 | )
9 |
10 | type MockOperation struct {
11 | ExecFn func(context.Context, apis.Bindings) (outputs.Outputs, error)
12 | }
13 |
14 | func (m MockOperation) Exec(ctx context.Context, bindings apis.Bindings) (outputs.Outputs, error) {
15 | return m.ExecFn(ctx, bindings)
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/engine/templating/convert.go:
--------------------------------------------------------------------------------
1 | package templating
2 |
3 | func convertSlice(in any) []any {
4 | data, ok := in.([]any)
5 | if !ok {
6 | return nil
7 | }
8 | out := []any{}
9 | for _, v := range data {
10 | out = append(out, convert(v))
11 | }
12 | return out
13 | }
14 |
15 | func convertMap(in any) map[string]any {
16 | data, ok := in.(map[any]any)
17 | if !ok {
18 | return nil
19 | }
20 | out := map[string]any{}
21 | for k, v := range data {
22 | out[k.(string)] = convert(v)
23 | }
24 | return out
25 | }
26 |
27 | func convert(in any) any {
28 | if result := convertSlice(in); result != nil {
29 | return result
30 | }
31 | if result := convertMap(in); result != nil {
32 | return result
33 | }
34 | return in
35 | }
36 |
--------------------------------------------------------------------------------
/pkg/engine/types.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/engine/namespacer"
5 | )
6 |
7 | type (
8 | Namespacer = namespacer.Namespacer
9 | )
10 |
--------------------------------------------------------------------------------
/pkg/loaders/config/default.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "sync"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha2"
7 | "github.com/kyverno/chainsaw/pkg/data"
8 | )
9 |
10 | func defaultConfiguration(_fs func() ([]byte, error)) (*v1alpha2.Configuration, error) {
11 | if _fs == nil {
12 | _fs = data.ConfigFile
13 | }
14 | bytes, err := _fs()
15 | if err != nil {
16 | return nil, err
17 | }
18 | return LoadBytes(bytes)
19 | }
20 |
21 | var DefaultConfiguration = sync.OnceValues(func() (*v1alpha2.Configuration, error) { return defaultConfiguration(nil) })
22 |
--------------------------------------------------------------------------------
/pkg/loaders/default.go:
--------------------------------------------------------------------------------
1 | package loaders
2 |
3 | import (
4 | "io/fs"
5 | "sync"
6 |
7 | "github.com/kyverno/chainsaw/pkg/data"
8 | "github.com/kyverno/pkg/ext/resource/loader"
9 | "sigs.k8s.io/kubectl-validate/pkg/openapiclient"
10 | )
11 |
12 | func defaultLoader(_fs func() (fs.FS, error)) (loader.Loader, error) {
13 | if _fs == nil {
14 | _fs = data.Crds
15 | }
16 | crdsFs, err := _fs()
17 | if err != nil {
18 | return nil, err
19 | }
20 | return loader.New(openapiclient.NewLocalCRDFiles(crdsFs))
21 | }
22 |
23 | var DefaultLoader = sync.OnceValues(func() (loader.Loader, error) { return defaultLoader(nil) })
24 |
--------------------------------------------------------------------------------
/pkg/loaders/testing/fake_loader.go:
--------------------------------------------------------------------------------
1 | package testing
2 |
3 | import (
4 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
5 | "k8s.io/apimachinery/pkg/runtime/schema"
6 | )
7 |
8 | type FakeLoader struct {
9 | LoadFn func(int, []byte) (schema.GroupVersionKind, unstructured.Unstructured, error)
10 | numCalls int
11 | }
12 |
13 | func (f *FakeLoader) Load(data []byte) (schema.GroupVersionKind, unstructured.Unstructured, error) {
14 | defer func() { f.numCalls++ }()
15 | return f.LoadFn(f.numCalls, data)
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/logging/log.go:
--------------------------------------------------------------------------------
1 | package logging
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | "github.com/fatih/color"
8 | "github.com/kyverno/chainsaw/pkg/client"
9 | )
10 |
11 | func Log(ctx context.Context, operation Operation, status Status, obj client.Object, color *color.Color, args ...fmt.Stringer) {
12 | if logger := getLogger(ctx); logger != nil {
13 | logger.Log(ctx, operation, status, obj, color, args...)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/logging/operation.go:
--------------------------------------------------------------------------------
1 | package logging
2 |
3 | type Operation string
4 |
5 | const (
6 | Apply Operation = "APPLY"
7 | Assert Operation = "ASSERT"
8 | Catch Operation = "CATCH"
9 | Cleanup Operation = "CLEANUP"
10 | Command Operation = "CMD"
11 | Create Operation = "CREATE"
12 | Delete Operation = "DELETE"
13 | Error Operation = "ERROR"
14 | Finally Operation = "FINALLY"
15 | Get Operation = "GET"
16 | Internal Operation = "INTERNAL"
17 | Patch Operation = "PATCH"
18 | Script Operation = "SCRIPT"
19 | Sleep Operation = "SLEEP"
20 | Stderr Operation = "STDERR"
21 | Stdout Operation = "STDOUT"
22 | Try Operation = "TRY"
23 | Update Operation = "UPDATE"
24 | )
25 |
--------------------------------------------------------------------------------
/pkg/logging/sink.go:
--------------------------------------------------------------------------------
1 | package logging
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/fatih/color"
7 | "github.com/kyverno/chainsaw/pkg/client"
8 | )
9 |
10 | type Sink interface {
11 | Log(string, string, Operation, Status, client.Object, *color.Color, ...fmt.Stringer)
12 | }
13 |
14 | type SinkFunc func(string, string, Operation, Status, client.Object, *color.Color, ...fmt.Stringer)
15 |
16 | func (f SinkFunc) Log(test string, step string, operation Operation, status Status, obj client.Object, color *color.Color, args ...fmt.Stringer) {
17 | f(test, step, operation, status, obj, color, args...)
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/logging/status.go:
--------------------------------------------------------------------------------
1 | package logging
2 |
3 | type Status string
4 |
5 | const (
6 | BeginStatus Status = "BEGIN"
7 | DoneStatus Status = "DONE"
8 | EndStatus Status = "END"
9 | ErrorStatus Status = "ERROR"
10 | LogStatus Status = "LOG"
11 | OkStatus Status = "OK"
12 | RunStatus Status = "RUN"
13 | SkippedStatus Status = "SKIP"
14 | WarnStatus Status = "WARN"
15 | // DoneStatus Status = "✅"
16 | // ErrorStatus Status = "❌"
17 | // LogStatus Status = "📄"
18 | // OkStatus Status = "🟢"
19 | // RunStatus Status = "🚧"
20 | // WarnStatus Status = "🟡"
21 | )
22 |
--------------------------------------------------------------------------------
/pkg/mocks/logger.go:
--------------------------------------------------------------------------------
1 | package mocks
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | "github.com/fatih/color"
8 | "github.com/kyverno/chainsaw/pkg/client"
9 | "github.com/kyverno/chainsaw/pkg/logging"
10 | )
11 |
12 | type Logger struct {
13 | Logs []string
14 | numCalls int
15 | }
16 |
17 | func (f *Logger) Log(_ context.Context, operation logging.Operation, status logging.Status, obj client.Object, color *color.Color, args ...fmt.Stringer) {
18 | defer func() { f.numCalls++ }()
19 | message := fmt.Sprintf("%s: %s - %v", operation, status, args)
20 | f.Logs = append(f.Logs, message)
21 | }
22 |
23 | func (f *Logger) NumCalls() int {
24 | return f.numCalls
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/model/config.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha2"
5 | )
6 |
7 | type Configuration = v1alpha2.ConfigurationSpec
8 |
--------------------------------------------------------------------------------
/pkg/model/summary.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "sync/atomic"
5 | )
6 |
7 | type SummaryResult interface {
8 | Passed() int32
9 | Failed() int32
10 | Skipped() int32
11 | }
12 |
13 | type Summary struct {
14 | passed atomic.Int32
15 | failed atomic.Int32
16 | skipped atomic.Int32
17 | }
18 |
19 | func (s *Summary) IncPassed() {
20 | s.passed.Add(1)
21 | }
22 |
23 | func (s *Summary) IncFailed() {
24 | s.failed.Add(1)
25 | }
26 |
27 | func (s *Summary) IncSkipped() {
28 | s.skipped.Add(1)
29 | }
30 |
31 | func (s *Summary) Passed() int32 {
32 | return s.passed.Load()
33 | }
34 |
35 | func (s *Summary) Failed() int32 {
36 | return s.failed.Load()
37 | }
38 |
39 | func (s *Summary) Skipped() int32 {
40 | return s.skipped.Load()
41 | }
42 |
--------------------------------------------------------------------------------
/pkg/model/summary_test.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "sync"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func Test_summay(t *testing.T) {
11 | var wg sync.WaitGroup
12 | var s Summary
13 | const count int32 = 10000
14 | for i := 0; i < int(count); i++ {
15 | wg.Add(3)
16 | go func() {
17 | defer wg.Done()
18 | s.IncFailed()
19 | }()
20 | go func() {
21 | defer wg.Done()
22 | s.IncPassed()
23 | }()
24 | go func() {
25 | defer wg.Done()
26 | s.IncSkipped()
27 | }()
28 | }
29 | wg.Wait()
30 | assert.Equal(t, count, s.Failed())
31 | assert.Equal(t, count, s.Passed())
32 | assert.Equal(t, count, s.Skipped())
33 | }
34 |
--------------------------------------------------------------------------------
/pkg/model/test.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
5 | )
6 |
7 | type Test = v1alpha1.Test
8 |
--------------------------------------------------------------------------------
/pkg/mutate/expression.go:
--------------------------------------------------------------------------------
1 | package mutate
2 |
3 | import (
4 | "context"
5 | "reflect"
6 |
7 | "github.com/kyverno/chainsaw/pkg/expressions"
8 | reflectutils "github.com/kyverno/kyverno-json/pkg/utils/reflect"
9 | )
10 |
11 | func parseExpression(ctx context.Context, value any) *expressions.Expression {
12 | if reflectutils.GetKind(value) != reflect.String {
13 | return nil
14 | }
15 | return expressions.Parse(ctx, reflect.ValueOf(value).String())
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/mutate/mutate.go:
--------------------------------------------------------------------------------
1 | package mutate
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis"
7 | "github.com/kyverno/kyverno-json/pkg/core/compilers"
8 | "k8s.io/apimachinery/pkg/util/validation/field"
9 | )
10 |
11 | func Mutate(ctx context.Context, compilers compilers.Compilers, path *field.Path, mutation Mutation, value any, bindings apis.Bindings) (any, error) {
12 | return mutation.mutate(ctx, compilers, path, value, bindings)
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/mutate/mutation.go:
--------------------------------------------------------------------------------
1 | package mutate
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis"
7 | "github.com/kyverno/kyverno-json/pkg/core/compilers"
8 | "k8s.io/apimachinery/pkg/util/validation/field"
9 | )
10 |
11 | type Mutation interface {
12 | mutate(context.Context, compilers.Compilers, *field.Path, any, apis.Bindings) (any, error)
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/runner/info.go:
--------------------------------------------------------------------------------
1 | package runner
2 |
3 | import (
4 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5 | )
6 |
7 | type TestInfo struct {
8 | Id int
9 | ScenarioId int
10 | Metadata metav1.ObjectMeta
11 | }
12 |
13 | type StepInfo struct {
14 | Id int
15 | }
16 |
17 | type OperationInfo struct {
18 | Id int
19 | ResourceId int
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/runner/internal/corpus_entry.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | // corpusEntry is from the public go testing which references an internal structure.
4 | // corpusEntry is an alias to the same type as internal/fuzz.CorpusEntry.
5 | // We use a type alias because we don't want to export this type, and we can't
6 | // import internal/fuzz from testing.
7 | type corpusEntry = struct {
8 | Parent string
9 | Path string
10 | Data []byte
11 | Values []any
12 | Generation int
13 | IsSeed bool
14 | }
15 |
--------------------------------------------------------------------------------
/pkg/runner/main_start.go:
--------------------------------------------------------------------------------
1 | package runner
2 |
3 | type mainstart interface {
4 | Run() int
5 | }
6 |
--------------------------------------------------------------------------------
/pkg/runner/mocks/registry.go:
--------------------------------------------------------------------------------
1 | package mocks
2 |
3 | import (
4 | "github.com/kyverno/chainsaw/pkg/client"
5 | "github.com/kyverno/chainsaw/pkg/engine/clusters"
6 | "k8s.io/client-go/rest"
7 | )
8 |
9 | type Registry struct {
10 | Client client.Client
11 | }
12 |
13 | func (r Registry) Register(string, clusters.Cluster) clusters.Registry {
14 | return r
15 | }
16 |
17 | func (r Registry) Lookup(string) clusters.Cluster {
18 | return nil
19 | }
20 |
21 | func (r Registry) Build(clusters.Cluster) (*rest.Config, client.Client, error) {
22 | return nil, r.Client, nil
23 | }
24 |
--------------------------------------------------------------------------------
/pkg/runner/names/step.go:
--------------------------------------------------------------------------------
1 | package names
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
7 | )
8 |
9 | func Step(step v1alpha1.TestStep, i int) string {
10 | if step.Name != "" {
11 | return step.Name
12 | }
13 | return fmt.Sprintf("step-%d", i+1)
14 | }
15 |
--------------------------------------------------------------------------------
/pkg/runner/names/step_test.go:
--------------------------------------------------------------------------------
1 | package names
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestStep(t *testing.T) {
11 | tests := []struct {
12 | name string
13 | step v1alpha1.TestStep
14 | i int
15 | want string
16 | }{{
17 | name: "no name",
18 | step: v1alpha1.TestStep{
19 | Name: "",
20 | },
21 | i: 10,
22 | want: "step-11",
23 | }, {
24 | name: "with name",
25 | step: v1alpha1.TestStep{
26 | Name: "foo",
27 | },
28 | i: 10,
29 | want: "foo",
30 | }}
31 | for _, tt := range tests {
32 | t.Run(tt.name, func(t *testing.T) {
33 | got := Step(tt.step, tt.i)
34 | assert.Equal(t, tt.want, got)
35 | })
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/pkg/runner/operations/operation.go:
--------------------------------------------------------------------------------
1 | package operations
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/kyverno/chainsaw/pkg/engine/outputs"
7 | enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
8 | )
9 |
10 | type Operation interface {
11 | Execute(context.Context, enginecontext.TestContext) (outputs.Outputs, error)
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/runner/operations/sleep.go:
--------------------------------------------------------------------------------
1 | package operations
2 |
3 | import (
4 | "context"
5 | "time"
6 |
7 | "github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
8 | opsleep "github.com/kyverno/chainsaw/pkg/engine/operations/sleep"
9 | "github.com/kyverno/chainsaw/pkg/engine/outputs"
10 | enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
11 | )
12 |
13 | type sleepAction struct {
14 | duration time.Duration
15 | }
16 |
17 | func (o sleepAction) Execute(ctx context.Context, tc enginecontext.TestContext) (outputs.Outputs, error) {
18 | op := opsleep.New(o.duration)
19 | return op.Exec(ctx, tc.Bindings())
20 | }
21 |
22 | func sleepOperation(op v1alpha1.Sleep) Operation {
23 | return sleepAction{
24 | duration: op.Duration.Duration,
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/utils/env/expand.go:
--------------------------------------------------------------------------------
1 | package env
2 |
3 | import (
4 | "os"
5 | )
6 |
7 | func Expand(env map[string]string, in ...string) []string {
8 | var args []string
9 | for _, arg := range in {
10 | expanded := os.Expand(arg, func(key string) string {
11 | // check $ key -> $$ becomes $
12 | if key == "$" {
13 | return "$"
14 | }
15 | // check the env map first
16 | if expanded, found := env[key]; found {
17 | return expanded
18 | }
19 | // check the env vars
20 | if expanded, found := os.LookupEnv(key); found {
21 | return expanded
22 | }
23 | // return the given key
24 | return "$" + key
25 | })
26 | args = append(args, expanded)
27 | }
28 | return args
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/utils/flag/flag.go:
--------------------------------------------------------------------------------
1 | package flag
2 |
3 | import (
4 | "github.com/spf13/pflag"
5 | )
6 |
7 | // IsSet returns true if a flag is set on the command line.
8 | func IsSet(flagSet *pflag.FlagSet, name string) bool {
9 | found := false
10 | flagSet.Visit(func(flag *pflag.Flag) {
11 | if flag.Name == name {
12 | found = true
13 | }
14 | })
15 | return found
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/utils/fs/check.go:
--------------------------------------------------------------------------------
1 | package fs
2 |
3 | import (
4 | "os"
5 | )
6 |
7 | func CheckFolders(paths ...string) error {
8 | for _, path := range paths {
9 | if _, err := os.Stat(path); err != nil {
10 | return err
11 | }
12 | }
13 | return nil
14 | }
15 |
--------------------------------------------------------------------------------
/pkg/utils/kube/namespace.go:
--------------------------------------------------------------------------------
1 | package kube
2 |
3 | import (
4 | corev1 "k8s.io/api/core/v1"
5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6 | )
7 |
8 | func Namespace(name string) corev1.Namespace {
9 | return corev1.Namespace{
10 | TypeMeta: metav1.TypeMeta{
11 | APIVersion: corev1.SchemeGroupVersion.String(),
12 | Kind: "Namespace",
13 | },
14 | ObjectMeta: metav1.ObjectMeta{
15 | Name: name,
16 | },
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/utils/kube/namespace_test.go:
--------------------------------------------------------------------------------
1 | package kube
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | corev1 "k8s.io/api/core/v1"
8 | )
9 |
10 | func TestNamespace(t *testing.T) {
11 | expectedName := "testNamespace"
12 | ns := Namespace(expectedName)
13 | assert.Equal(t, corev1.SchemeGroupVersion.String(), ns.APIVersion)
14 | assert.Equal(t, "Namespace", ns.Kind)
15 | assert.Equal(t, expectedName, ns.Name)
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/utils/kube/unstructured.go:
--------------------------------------------------------------------------------
1 | package kube
2 |
3 | import (
4 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
5 | "k8s.io/apimachinery/pkg/runtime"
6 | )
7 |
8 | func ToUnstructured(obj any) unstructured.Unstructured {
9 | data, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
10 | if err != nil {
11 | panic(err)
12 | }
13 | return unstructured.Unstructured{Object: data}
14 | }
15 |
--------------------------------------------------------------------------------
/pkg/utils/kube/unstructured_test.go:
--------------------------------------------------------------------------------
1 | package kube
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
8 | "k8s.io/utils/ptr"
9 | )
10 |
11 | func TestToUnstructured(t *testing.T) {
12 | var nilPtr *int
13 | assert.Panics(t, func() {
14 | ToUnstructured(nilPtr)
15 | })
16 | assert.Equal(t, ToUnstructured(ptr.To(Namespace("foo"))), unstructured.Unstructured{
17 | Object: map[string]any{
18 | "apiVersion": "v1",
19 | "kind": "Namespace",
20 | "metadata": map[string]any{
21 | "creationTimestamp": nil,
22 | "name": "foo",
23 | },
24 | "spec": map[string]any{},
25 | "status": map[string]any{},
26 | },
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/utils/maps/merge.go:
--------------------------------------------------------------------------------
1 | package maps
2 |
3 | func Merge(a, b map[string]any) map[string]any {
4 | out := make(map[string]any, len(a))
5 | for k, v := range a {
6 | out[k] = v
7 | }
8 | for k, v := range b {
9 | if v, ok := v.(map[string]any); ok {
10 | if bv, ok := out[k]; ok {
11 | if bv, ok := bv.(map[string]any); ok {
12 | out[k] = Merge(bv, v)
13 | continue
14 | }
15 | }
16 | }
17 | out[k] = v
18 | }
19 | return out
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/utils/yaml/yaml.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "gopkg.in/yaml.v3"
5 | )
6 |
7 | func remarshal(document []byte, unmarshal func(in []byte, out interface{}) (err error)) ([]byte, error) {
8 | if unmarshal == nil {
9 | unmarshal = yaml.Unmarshal
10 | }
11 | var pre map[string]any
12 | err := unmarshal(document, &pre)
13 | if err != nil {
14 | return nil, err
15 | }
16 | return yaml.Marshal(pre)
17 | }
18 |
19 | func Remarshal(document []byte) ([]byte, error) {
20 | return remarshal(document, nil)
21 | }
22 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | cairosvg
2 | lunr
3 | mike
4 | mkdocs
5 | mkdocs-include-markdown-plugin
6 | mkdocs-material
7 | mkdocs-minify-plugin
8 | mkdocs-redirects
9 | mkdocs-rss-plugin
10 | git+https://github.com/eddycharly/openapi2jsonschema.git@v3
11 | Pillow
12 |
--------------------------------------------------------------------------------
/testdata/commands/assert/assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/commands/build/docs/help.txt:
--------------------------------------------------------------------------------
1 | Build tests documentation
2 |
3 | Usage:
4 | chainsaw docs [flags]
5 |
6 | Flags:
7 | --catalog string Path to the built test catalog file
8 | -h, --help help for docs
9 | --readme-file string Name of the built docs file (default "README.md")
10 | --test-dir stringArray Directories containing test cases to run
11 | --test-file string Name of the test file (default "chainsaw-test")
12 |
--------------------------------------------------------------------------------
/testdata/commands/build/help.txt:
--------------------------------------------------------------------------------
1 | Build commands
2 |
3 | Usage:
4 | chainsaw build [flags]
5 | chainsaw build [command]
6 |
7 | Available Commands:
8 | docs Build tests documentation
9 |
10 | Flags:
11 | -h, --help help for build
12 |
13 | Use "chainsaw build [command] --help" for more information about a command.
14 |
--------------------------------------------------------------------------------
/testdata/commands/create/help.txt:
--------------------------------------------------------------------------------
1 | Create Chainsaw resources
2 |
3 | Usage:
4 | chainsaw create [flags]
5 | chainsaw create [command]
6 |
7 | Available Commands:
8 | test Create a Chainsaw test
9 |
10 | Flags:
11 | -h, --help help for create
12 |
13 | Use "chainsaw create [command] --help" for more information about a command.
14 |
--------------------------------------------------------------------------------
/testdata/commands/create/test/help.txt:
--------------------------------------------------------------------------------
1 | Create a Chainsaw test
2 |
3 | Usage:
4 | chainsaw test [flags]
5 |
6 | Flags:
7 | --description If set, adds description when applicable (default true)
8 | --force If set, existing test will be deleted if needed
9 | -h, --help help for test
10 | --save If set, created test will be saved
11 |
--------------------------------------------------------------------------------
/testdata/commands/docs/help.txt:
--------------------------------------------------------------------------------
1 | Generate reference documentation
2 |
3 | Usage:
4 | chainsaw docs [flags]
5 |
6 | Flags:
7 | --autogenTag Determines if the generated docs should contain a timestamp (default true)
8 | -h, --help help for docs
9 | -o, --output string Output path (default ".")
10 | --website Website version
11 |
--------------------------------------------------------------------------------
/testdata/commands/docs/invalid-output.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/commands/docs/invalid-output.txt
--------------------------------------------------------------------------------
/testdata/commands/export/help.txt:
--------------------------------------------------------------------------------
1 | Export commands
2 |
3 | Usage:
4 | chainsaw export [flags]
5 | chainsaw export [command]
6 |
7 | Available Commands:
8 | schemas Export JSON schemas
9 |
10 | Flags:
11 | -h, --help help for export
12 |
13 | Use "chainsaw export [command] --help" for more information about a command.
14 |
--------------------------------------------------------------------------------
/testdata/commands/export/schemas/help.txt:
--------------------------------------------------------------------------------
1 | Export JSON schemas
2 |
3 | Usage:
4 | chainsaw schemas [flags]
5 |
6 | Flags:
7 | -h, --help help for schemas
8 |
--------------------------------------------------------------------------------
/testdata/commands/lint/configuration/configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": "chainsaw.kyverno.io/v1alpha1",
3 | "kind": "Configuration",
4 | "metadata": {
5 | "name": "valid",
6 | "namespace": "kyverno"
7 | },
8 | "spec": {
9 | "timeouts": {
10 | "apply": "5s",
11 | "assert": "10s",
12 | "error": "10s",
13 | "delete": "5s",
14 | "cleanup": "5s",
15 | "exec": "10s"
16 | },
17 | "skipDelete": true,
18 | "failFast": true,
19 | "parallel": 5,
20 | "reportFormat": "JSON",
21 | "reportName": "custom-chainsaw-report",
22 | "namespace": "test-namespace",
23 | "fullName": true,
24 | "includeTestRegex": "^include-.*",
25 | "excludeTestRegex": "^exclude-.*"
26 | }
27 | }
--------------------------------------------------------------------------------
/testdata/commands/lint/configuration/configuration.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: valid
5 | namespace: kyverno
6 | spec:
7 | timeouts:
8 | apply: 5s
9 | assert: 10s
10 | error: 10s
11 | delete: 5s
12 | cleanup: 5s
13 | exec: 10s
14 | skipDelete: true
15 | failFast: true
16 | parallel: 5
17 | reportFormat: JSON
18 | reportName: custom-chainsaw-report
19 | namespace: test-namespace
20 | fullName: true
21 | includeTestRegex: ^include-.*
22 | excludeTestRegex: ^exclude-.*
23 |
--------------------------------------------------------------------------------
/testdata/commands/lint/configuration/pass.txt:
--------------------------------------------------------------------------------
1 | Processing input...
2 | The document is valid
3 |
--------------------------------------------------------------------------------
/testdata/commands/lint/configuration/wrong-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": "chainsaw.kyverno.io/v1alpha2",
3 | "kind": "Configurations",
4 | "metadata": {
5 | "name": "valid",
6 | "namespace": "kyverno"
7 | },
8 | "spec": {
9 | "timeouts": {
10 | "apply": "5s",
11 | "assert": "10s",
12 | "error": "10s",
13 | "delete": "5s",
14 | "cleanup": "5s",
15 | "exec": "10s"
16 | },
17 | "skipDelete": true,
18 | "failFast": true,
19 | "parallel": 5,
20 | "reportFormat": "JSON",
21 | "reportName": "custom-chainsaw-report",
22 | "namespace": "test-namespace",
23 | "fullName": true,
24 | "includeTestRegex": "^include-.*",
25 | "excludeTestRegex": "^exclude-.*"
26 | }
27 | }
--------------------------------------------------------------------------------
/testdata/commands/lint/configuration/wrong-configuration.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha2
2 | kind: Configurations
3 | metadata:
4 | name: valid
5 | namespace: kyverno
6 | spec:
7 | timeouts:
8 | apply: 5s
9 | assert: 10s
10 | error: 10s
11 | delete: 5s
12 | cleanup: 5s
13 | exec: 10s
14 | skipDelete: true
15 | failFast: true
16 | parallel: 5
17 | reportFormat: JSON
18 | reportName: custom-chainsaw-report
19 | namespace: test-namespace
20 | fullName: true
21 | includeTestRegex: ^include-.*
22 | excludeTestRegex: ^exclude-.*
23 |
--------------------------------------------------------------------------------
/testdata/commands/lint/test/pass.txt:
--------------------------------------------------------------------------------
1 | Processing input...
2 | The document is valid
3 |
--------------------------------------------------------------------------------
/testdata/commands/migrate/help.txt:
--------------------------------------------------------------------------------
1 | Migrate resources to Chainsaw
2 |
3 | Usage:
4 | chainsaw migrate [flags]
5 | chainsaw migrate [command]
6 |
7 | Available Commands:
8 | kuttl Migrate KUTTL resources to Chainsaw
9 |
10 | Flags:
11 | -h, --help help for migrate
12 |
13 | Use "chainsaw migrate [command] --help" for more information about a command.
14 |
--------------------------------------------------------------------------------
/testdata/commands/migrate/kuttl/config/help.txt:
--------------------------------------------------------------------------------
1 | Migrate KUTTL config to Chainsaw
2 |
3 | Usage:
4 | chainsaw config [flags]
5 |
6 | Flags:
7 | --cleanup If set, delete converted files
8 | -h, --help help for config
9 | --save If set, converted files will be saved
10 |
--------------------------------------------------------------------------------
/testdata/commands/migrate/kuttl/config/out-save.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/commands/migrate/kuttl/config/out-save.txt
--------------------------------------------------------------------------------
/testdata/commands/migrate/kuttl/config/out.txt:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/configuration-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Configuration
4 | metadata:
5 | creationTimestamp: null
6 | name: configuration
7 | spec:
8 | parallel: 4
9 | template: false
10 | timeouts:
11 | apply: 5m0s
12 | assert: 5m0s
13 | cleanup: 5m0s
14 | delete: 5m0s
15 | error: 5m0s
16 | exec: 5m0s
17 |
18 |
--------------------------------------------------------------------------------
/testdata/commands/migrate/kuttl/help.txt:
--------------------------------------------------------------------------------
1 | Migrate KUTTL resources to Chainsaw
2 |
3 | Usage:
4 | chainsaw kuttl [flags]
5 | chainsaw kuttl [command]
6 |
7 | Available Commands:
8 | config Migrate KUTTL config to Chainsaw
9 | tests Migrate KUTTL tests to Chainsaw
10 |
11 | Flags:
12 | -h, --help help for kuttl
13 |
14 | Use "chainsaw kuttl [command] --help" for more information about a command.
15 |
--------------------------------------------------------------------------------
/testdata/commands/migrate/kuttl/tests/help.txt:
--------------------------------------------------------------------------------
1 | Migrate KUTTL tests to Chainsaw
2 |
3 | Usage:
4 | chainsaw tests [flags]
5 |
6 | Flags:
7 | --cleanup If set, delete converted files
8 | -h, --help help for tests
9 | --save If set, converted files will be saved
10 |
--------------------------------------------------------------------------------
/testdata/commands/migrate/kuttl/tests/out-save.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/commands/migrate/kuttl/tests/out-save.txt
--------------------------------------------------------------------------------
/testdata/commands/renovate/config/help.txt:
--------------------------------------------------------------------------------
1 | Upgrade Chainsaw configuration to the latest version
2 |
3 | Usage:
4 | chainsaw config [flags]
5 |
6 | Flags:
7 | -h, --help help for config
8 | --save If set, converted files will be saved
9 |
--------------------------------------------------------------------------------
/testdata/commands/renovate/config/out-save.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/commands/renovate/config/out-save.txt
--------------------------------------------------------------------------------
/testdata/commands/renovate/config/v1alpha1-default.txt:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/configuration-chainsaw-v1alpha2.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha2
3 | kind: Configuration
4 | metadata:
5 | name: default
6 | spec:
7 | report:
8 | name: chainsaw-report
9 |
10 |
--------------------------------------------------------------------------------
/testdata/commands/renovate/help.txt:
--------------------------------------------------------------------------------
1 | Upgrade Chainsaw resources
2 |
3 | Usage:
4 | chainsaw renovate [flags]
5 | chainsaw renovate [command]
6 |
7 | Available Commands:
8 | config Upgrade Chainsaw configuration to the latest version
9 |
10 | Flags:
11 | -h, --help help for renovate
12 |
13 | Use "chainsaw renovate [command] --help" for more information about a command.
14 |
--------------------------------------------------------------------------------
/testdata/commands/root/help.txt:
--------------------------------------------------------------------------------
1 | Stronger tool for e2e testing
2 |
3 | Usage:
4 | chainsaw [flags]
5 |
6 | Flags:
7 | -h, --help help for chainsaw
8 |
--------------------------------------------------------------------------------
/testdata/commands/test/config/config_all_fields.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: valid
5 | namespace: kyverno
6 | spec:
7 | timeouts:
8 | apply: 5s
9 | assert: 10s
10 | error: 10s
11 | delete: 5s
12 | cleanup: 5s
13 | exec: 10s
14 | skipDelete: true
15 | failFast: true
16 | parallel: 5
17 | reportFormat: JSON
18 | reportName: custom-chainsaw-report
19 | namespace: test-namespace
20 | fullName: true
21 | includeTestRegex: ^include-.*
22 | excludeTestRegex: ^exclude-.*
23 |
--------------------------------------------------------------------------------
/testdata/commands/test/config/empty_config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: default
5 | namespace: kyverno
6 |
--------------------------------------------------------------------------------
/testdata/commands/test/config/wrong_format_config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: default
5 | namespace: kyverno
6 | spec:
7 | foo: bar
8 |
--------------------------------------------------------------------------------
/testdata/commands/test/config/wrong_kind_config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: foo
3 | metadata:
4 | name: default
5 | namespace: kyverno
6 |
--------------------------------------------------------------------------------
/testdata/commands/test/default.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading default configuration...
3 | - Using test file: chainsaw-test
4 | - TestDirs [.]
5 | - SkipDelete false
6 | - FailFast false
7 | - Namespace ''
8 | - FullName false
9 | - IncludeTestRegex ''
10 | - ExcludeTestRegex ''
11 | - ApplyTimeout 5s
12 | - AssertTimeout 30s
13 | - CleanupTimeout 30s
14 | - DeleteTimeout 15s
15 | - ErrorTimeout 30s
16 | - ExecTimeout 5s
17 | - DeletionPropagationPolicy Background
18 | - Template true
19 | - NoCluster false
20 | - PauseOnFailure false
21 | Loading tests...
22 | Loading values...
23 | Running tests...
24 | Tests Summary...
25 | - Passed tests 0
26 | - Failed tests 0
27 | - Skipped tests 0
28 | Done.
29 |
--------------------------------------------------------------------------------
/testdata/commands/test/with_regex.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading default configuration...
3 | - Using test file: chainsaw-test
4 | - TestDirs [.]
5 | - SkipDelete false
6 | - FailFast false
7 | - Namespace ''
8 | - FullName false
9 | - IncludeTestRegex 'test[4-6]'
10 | - ExcludeTestRegex 'test[1-3]'
11 | - ApplyTimeout 5s
12 | - AssertTimeout 30s
13 | - CleanupTimeout 30s
14 | - DeleteTimeout 15s
15 | - ErrorTimeout 30s
16 | - ExecTimeout 5s
17 | - DeletionPropagationPolicy Background
18 | - Template true
19 | - NoCluster false
20 | - PauseOnFailure false
21 | Loading tests...
22 | Loading values...
23 | Running tests...
24 | Tests Summary...
25 | - Passed tests 0
26 | - Failed tests 0
27 | - Skipped tests 0
28 | Done.
29 |
--------------------------------------------------------------------------------
/testdata/commands/test/with_repeat_count.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading default configuration...
3 | - Using test file: chainsaw-test
4 | - TestDirs [.]
5 | - SkipDelete false
6 | - FailFast false
7 | - Namespace ''
8 | - FullName false
9 | - IncludeTestRegex ''
10 | - ExcludeTestRegex ''
11 | - ApplyTimeout 5s
12 | - AssertTimeout 30s
13 | - CleanupTimeout 30s
14 | - DeleteTimeout 15s
15 | - ErrorTimeout 30s
16 | - ExecTimeout 5s
17 | - DeletionPropagationPolicy Background
18 | - RepeatCount 3
19 | - Template true
20 | - NoCluster false
21 | - PauseOnFailure false
22 | Loading tests...
23 | Loading values...
24 | Running tests...
25 | Tests Summary...
26 | - Passed tests 0
27 | - Failed tests 0
28 | - Skipped tests 0
29 | Done.
30 |
--------------------------------------------------------------------------------
/testdata/commands/test/with_suppress.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading default configuration...
3 | - Using test file: chainsaw-test
4 | - Timeout 30s
5 | - TestDirs [.]
6 | - SkipDelete false
7 | - FailFast false
8 | - ReportFormat ''
9 | - ReportName ''
10 | - Namespace ''
11 | - FullName false
12 | - IncludeTestRegex ''
13 | - ExcludeTestRegex ''
14 | - ApplyTimeout 5s
15 | - AssertTimeout 30s
16 | - CleanupTimeout 30s
17 | - DeleteTimeout 15s
18 | - ErrorTimeout 30s
19 | - ExecTimeout 5s
20 | - DeletionPropagationPolicy Background
21 | - Template true
22 | - NoCluster false
23 | - PauseOnFailure false
24 | Loading tests...
25 | Loading values...
26 | Running tests...
27 | Tests Summary...
28 | - Passed tests 0
29 | - Failed tests 0
30 | - Skipped tests 0
31 | Done.
32 |
--------------------------------------------------------------------------------
/testdata/commands/test/with_test_dirs.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading default configuration...
3 | - Using test file: chainsaw-test
4 | - TestDirs [.. .]
5 | - SkipDelete false
6 | - FailFast false
7 | - Namespace ''
8 | - FullName false
9 | - IncludeTestRegex ''
10 | - ExcludeTestRegex ''
11 | - ApplyTimeout 5s
12 | - AssertTimeout 30s
13 | - CleanupTimeout 30s
14 | - DeleteTimeout 15s
15 | - ErrorTimeout 30s
16 | - ExecTimeout 5s
17 | - DeletionPropagationPolicy Background
18 | - Template true
19 | - NoCluster false
20 | - PauseOnFailure false
21 | Loading tests...
22 | Loading values...
23 | Running tests...
24 | Tests Summary...
25 | - Passed tests 0
26 | - Failed tests 0
27 | - Skipped tests 0
28 | Done.
29 |
--------------------------------------------------------------------------------
/testdata/commands/test/with_timeout.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading default configuration...
3 | - Using test file: chainsaw-test
4 | - TestDirs [.]
5 | - SkipDelete false
6 | - FailFast false
7 | - Namespace ''
8 | - FullName false
9 | - IncludeTestRegex ''
10 | - ExcludeTestRegex ''
11 | - ApplyTimeout 10s
12 | - AssertTimeout 30s
13 | - CleanupTimeout 30s
14 | - DeleteTimeout 15s
15 | - ErrorTimeout 30s
16 | - ExecTimeout 5s
17 | - DeletionPropagationPolicy Background
18 | - Template true
19 | - NoCluster false
20 | - PauseOnFailure false
21 | Loading tests...
22 | Loading values...
23 | Running tests...
24 | Tests Summary...
25 | - Passed tests 0
26 | - Failed tests 0
27 | - Skipped tests 0
28 | Done.
29 |
--------------------------------------------------------------------------------
/testdata/commands/test/wrong_format_config.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading config (../../../testdata/commands/test/config/wrong_format_config.yaml)...
3 |
--------------------------------------------------------------------------------
/testdata/commands/test/wrong_kind_config.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Loading config (../../../testdata/commands/test/config/wrong_kind_config.yaml)...
3 |
--------------------------------------------------------------------------------
/testdata/commands/test/wrong_kind_config_err.txt:
--------------------------------------------------------------------------------
1 | Error: failed to load configuration (failed to parse document (failed to retrieve validator: kind foo not found in chainsaw.kyverno.io/v1alpha1 groupversion))
2 |
--------------------------------------------------------------------------------
/testdata/commands/version/help.txt:
--------------------------------------------------------------------------------
1 | Print the version informations
2 |
3 | Usage:
4 | chainsaw version [flags]
5 |
6 | Flags:
7 | -h, --help help for version
8 |
--------------------------------------------------------------------------------
/testdata/commands/version/out.txt:
--------------------------------------------------------------------------------
1 | Version: ---
2 | Time: ---
3 | Git commit ID: ---
4 |
--------------------------------------------------------------------------------
/testdata/config/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: default
5 | data:
6 | foo: bar
--------------------------------------------------------------------------------
/testdata/config/empty.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/config/empty.yaml
--------------------------------------------------------------------------------
/testdata/config/multiple.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: default
5 | spec: {}
6 | ---
7 | apiVersion: chainsaw.kyverno.io/v1alpha1
8 | kind: Configuration
9 | metadata:
10 | name: timeout-1m
11 | spec:
12 | timeouts:
13 | assert: 1m
14 |
--------------------------------------------------------------------------------
/testdata/config/v1alpha1/bad-catch.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: default
5 | spec:
6 | catch:
7 | - description: this is a bad catch because it contains two actions
8 | sleep:
9 | duration: 1m
10 | events: {}
11 |
--------------------------------------------------------------------------------
/testdata/config/v1alpha1/custom-config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: custom-config
5 | spec:
6 | timeouts:
7 | apply: 5s
8 | assert: 10s
9 | error: 10s
10 | delete: 5s
11 | cleanup: 5s
12 | exec: 10s
13 | skipDelete: true
14 | testFile: custom-test.yaml
15 | failFast: true
16 | parallel: 4
17 | reportFormat: "JSON"
18 | reportName: "custom-report"
19 | fullName: true
20 | includeTestRegex: "include-*"
21 | excludeTestRegex: "exclude-*"
22 | forceTerminationGracePeriod: 10s
23 |
--------------------------------------------------------------------------------
/testdata/config/v1alpha1/default.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Configuration
3 | metadata:
4 | name: default
5 | spec: {}
--------------------------------------------------------------------------------
/testdata/discovery/empty-test/fake.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/discovery/empty-test/fake.json
--------------------------------------------------------------------------------
/testdata/discovery/manifests/01-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: chainsaw-quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/discovery/manifests/01-configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: chainsaw-quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/discovery/manifests/01-errors.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: chainsaw-quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/discovery/multiple-tests/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 | spec:
6 | steps:
7 | - name: create configmap
8 | try:
9 | - apply:
10 | file: configmap.yaml
11 | - name: assert configmap
12 | try:
13 | - assert:
14 | file: configmap.yaml
15 | ---
16 | apiVersion: chainsaw.kyverno.io/v1alpha1
17 | kind: Test
18 | metadata:
19 | name: test-2
20 | spec:
21 | steps:
22 | - name: create configmap
23 | try:
24 | - apply:
25 | file: configmap.yaml
26 | - name: assert configmap
27 | try:
28 | - assert:
29 | file: configmap.yaml
30 |
--------------------------------------------------------------------------------
/testdata/discovery/not-a-test/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: chainsaw-quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/discovery/test-yml/chainsaw-test.yml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test
5 | spec:
6 | steps:
7 | - name: create configmap
8 | try:
9 | - apply:
10 | file: configmap.yaml
11 | - name: assert configmap
12 | try:
13 | - assert:
14 | file: configmap.yaml
15 |
--------------------------------------------------------------------------------
/testdata/discovery/test/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test
5 | spec:
6 | steps:
7 | - name: create configmap
8 | try:
9 | - apply:
10 | file: configmap.yaml
11 | - name: assert configmap
12 | try:
13 | - assert:
14 | file: configmap.yaml
15 |
--------------------------------------------------------------------------------
/testdata/e2e/config.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../.schemas/json/configuration-chainsaw-v1alpha2.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha2
3 | kind: Configuration
4 | metadata:
5 | name: configuration
6 | spec:
7 | discovery:
8 | fullName: true
9 | execution:
10 | failFast: true
11 | forceTerminationGracePeriod: 5s
12 | parallel: 1
13 | namespace:
14 | compiler: cel
15 | template:
16 | metadata:
17 | annotations:
18 | from-config-file: (string("hello"))
19 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/apply-outputs/resources.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: first
5 | data:
6 | foo: bar
7 | ---
8 | apiVersion: v1
9 | kind: ConfigMap
10 | metadata:
11 | name: second
12 | data:
13 | foo: bar
14 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/array-assertion/README.md:
--------------------------------------------------------------------------------
1 | # Test: `array-assertions`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/array-assertion/assertions.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: example
5 | spec:
6 | # iterate over all containers having `name: container-1`
7 | ~.(containers[?name == 'container-1']):
8 | image: nginx-1
9 | # iterate over all containers, bind `$index` to the element index
10 | ~index.(containers):
11 | image: (join('-', ['nginx', to_string($index + `1`)]))
12 | # nested iteration
13 | ~index2.(containers):
14 | ~.(env):
15 | name: (join('_', ['ENV', to_string($index2 + `1`)]))
16 | value: (join('-', ['value', to_string($index2 + `1`)]))
17 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/array-assertion/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: array-assertions
6 | spec:
7 | steps:
8 | - try:
9 | - apply:
10 | file: resources.yaml
11 | - assert:
12 | file: assertions.yaml
13 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/array-assertion/resources.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: example
5 | spec:
6 | containers:
7 | - name: container-1
8 | image: nginx-1
9 | env:
10 | - name: ENV_1
11 | value: value-1
12 | - name: container-2
13 | image: nginx-2
14 | env:
15 | - name: ENV_2
16 | value: value-2
17 | - name: container-3
18 | image: nginx-3
19 | env:
20 | - name: ENV_3
21 | value: value-3
22 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/assertion-tree/README.md:
--------------------------------------------------------------------------------
1 | # Test: `assertion-tree`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `assert` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/assertion-tree/assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | labels:
5 | k8s-app: kube-dns
6 | namespace: kube-system
7 | spec:
8 | template:
9 | (spec)->specBinding:
10 | # the ~ modifier tells Chainsaw to iterate over the array elements
11 | ~.(containers):
12 | ($specBinding.securityContext != null || securityContext != null): true
13 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/assertion-tree/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: assertion-tree
6 | spec:
7 | steps:
8 | - try:
9 | - assert:
10 | file: assert.yaml
11 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/basic/README.md:
--------------------------------------------------------------------------------
1 | # Test: `basic`
2 |
3 | This is a very simple test that creates a configmap and checks the content is as expected.
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 3 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | This steps applies the configmap in the cluster and checks the configmap content.
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | Create the configmap. |
20 | | 2 | `assert` | 0 | 0 | Check the configmap content. |
21 | | 3 | `script` | 0 | 0 | *No description* |
22 |
23 | ---
24 |
25 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/basic/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: basic
6 | spec:
7 | description: This is a very simple test that creates a configmap and checks the content is as expected.
8 | steps:
9 | - description: This steps applies the configmap in the cluster and checks the configmap content.
10 | try:
11 | - description: Create the configmap.
12 | apply:
13 | file: configmap.yaml
14 | - description: Check the configmap content.
15 | assert:
16 | file: configmap-assert.yaml
17 | - script:
18 | content: cd .. && kubectl get pod -A
--------------------------------------------------------------------------------
/testdata/e2e/examples/basic/configmap-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/basic/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/catch/README.md:
--------------------------------------------------------------------------------
1 | # Test: `catch`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 2 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | #### Catch
23 |
24 | | # | Operation | Bindings | Outputs | Description |
25 | |:-:|---|:-:|:-:|---|
26 | | 1 | `events` | 0 | 0 | *No description* |
27 | | 2 | `describe` | 0 | 0 | *No description* |
28 |
29 | ---
30 |
31 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/command-output/README.md:
--------------------------------------------------------------------------------
1 | # Test: `command-output`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [Check bad kubectl command](#step-Check bad kubectl command) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `Check bad kubectl command`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `script` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/command-output/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: command-output
6 | spec:
7 | steps:
8 | - name: Check bad kubectl command
9 | try:
10 | - script:
11 | content: kubectl foo
12 | check:
13 | # This checks that the result of the content was an error.
14 | ($error != null): true
15 | # This check below ensures that the string 'top' is found in stderr or else fails
16 | (contains($stderr, 'top')): true
17 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/delete/cms.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: quick-start
5 | data:
6 | foo: bar
7 | ---
8 | apiVersion: v1
9 | kind: ConfigMap
10 | metadata:
11 | name: quick-start-2
12 | data:
13 | foo: bar
14 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/deployment/README.md:
--------------------------------------------------------------------------------
1 | # Test: `deployment`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/deployment/assertions.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | labels:
5 | app: nginx
6 | spec: {}
--------------------------------------------------------------------------------
/testdata/e2e/examples/deployment/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: deployment
6 | spec:
7 | steps:
8 | - try:
9 | - apply:
10 | file: resources.yaml
11 | - assert:
12 | file: assertions.yaml
13 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/deployment/resources.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: example
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: nginx
9 | template:
10 | metadata:
11 | labels:
12 | app: nginx
13 | spec:
14 | containers:
15 | - name: nginx
16 | image: nginx:1.14.2
17 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/field-validation/README.md:
--------------------------------------------------------------------------------
1 | # Test: `field-validation`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/field-validation/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: field-validation
6 | spec:
7 | steps:
8 | - try:
9 | - apply:
10 | resource:
11 | apiVersion: v1
12 | kind: ConfigMap
13 | metadata:
14 | name: chainsaw-quick-start
15 | data:
16 | foo: bar
17 | bar: baz
18 | expect:
19 | - check:
20 | ($error): |-
21 | ConfigMap in version "v1" cannot be handled as a ConfigMap: strict decoding error: unknown field "bar"
22 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/finally/README.md:
--------------------------------------------------------------------------------
1 | # Test: `finally`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 2 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | #### Finally
23 |
24 | | # | Operation | Bindings | Outputs | Description |
25 | |:-:|---|:-:|:-:|---|
26 | | 1 | `events` | 0 | 0 | *No description* |
27 | | 2 | `script` | 0 | 0 | *No description* |
28 |
29 | ---
30 |
31 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/inline/README.md:
--------------------------------------------------------------------------------
1 | # Test: `inline`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/inline/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: inline
6 | spec:
7 | steps:
8 | - try:
9 | - apply:
10 | resource:
11 | apiVersion: v1
12 | kind: ConfigMap
13 | metadata:
14 | name: quick-start
15 | data:
16 | foo: bar
17 | - assert:
18 | resource:
19 | apiVersion: v1
20 | kind: ConfigMap
21 | metadata:
22 | name: quick-start
23 | data:
24 | foo: bar
25 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/jmespath-label-condition/README.md:
--------------------------------------------------------------------------------
1 | # Test: `jmespath-label-condition`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/jmespath-label-condition/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: jmespath-label-condition
6 | spec:
7 | steps:
8 | - try:
9 | - apply:
10 | resource:
11 | apiVersion: v1
12 | kind: ConfigMap
13 | metadata:
14 | name: jmespath-label-condition
15 | labels:
16 | type: my-first-configmap
17 | - assert:
18 | resource:
19 | apiVersion: v1
20 | kind: ConfigMap
21 | metadata:
22 | labels:
23 | type:
24 | (starts_with(@, 'my-first-')): true
25 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/k8s-server-version/README.md:
--------------------------------------------------------------------------------
1 | # Test: `k8s-server-version`
2 |
3 | *No description*
4 |
5 | ## Bindings
6 |
7 | | # | Name | Value |
8 | |:-:|---|---|
9 | | 1 | `version` | "(x_k8s_server_version($config))" |
10 |
11 | ## Steps
12 |
13 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
14 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
15 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
16 |
17 | ### Step: `step-1`
18 |
19 | *No description*
20 |
21 | #### Try
22 |
23 | | # | Operation | Bindings | Outputs | Description |
24 | |:-:|---|:-:|:-:|---|
25 | | 1 | `script` | 0 | 0 | *No description* |
26 |
27 | ---
28 |
29 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/k8s-server-version/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: k8s-server-version
6 | spec:
7 | bindings:
8 | - name: version
9 | value: (x_k8s_server_version($config))
10 | steps:
11 | - try:
12 | - script:
13 | env:
14 | - name: K8S_VERSION
15 | value: (to_string($version))
16 | content: |
17 | set -e
18 | echo $K8S_VERSION
19 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/list/README.md:
--------------------------------------------------------------------------------
1 | # Test: `list`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 3 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 | | 3 | `assert` | 0 | 0 | *No description* |
22 |
23 | ---
24 |
25 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/list/list.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - apiVersion: v1
5 | kind: ConfigMap
6 | metadata:
7 | name: cm-1
8 | namespace: default
9 | data:
10 | key: 'yes'
11 | - apiVersion: v1
12 | kind: ConfigMap
13 | metadata:
14 | name: cm-2
15 | namespace: default
16 | data:
17 | key: 'no'
18 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/namespace-template-config/README.md:
--------------------------------------------------------------------------------
1 | # Test: `namespace-template-config`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `assert` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/namespace-template-config/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: namespace-template-config
6 | spec:
7 | steps:
8 | - try:
9 | - assert:
10 | resource:
11 | apiVersion: v1
12 | kind: Namespace
13 | metadata:
14 | annotations:
15 | from-config-file: hello
16 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/namespace-template/README.md:
--------------------------------------------------------------------------------
1 | # Test: `namespace-template`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `assert` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/namespace-template/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: namespace-template
6 | spec:
7 | namespaceTemplate:
8 | metadata:
9 | name: foo
10 | annotations:
11 | keptn.sh/lifecycle-toolkit: enabled
12 | steps:
13 | - try:
14 | - assert:
15 | resource:
16 | apiVersion: v1
17 | kind: Namespace
18 | metadata:
19 | name: foo
20 | annotations:
21 | keptn.sh/lifecycle-toolkit: enabled
22 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/negative-testing/resource/README.md:
--------------------------------------------------------------------------------
1 | # Test: `negative-resource`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/negative-testing/resource/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: negative-resource
6 | spec:
7 | steps:
8 | - try:
9 | - apply:
10 | file: resources.yaml
11 | expect:
12 | - match:
13 | apiVersion: v1
14 | kind: ConfigMap
15 | metadata:
16 | name: bad
17 | check:
18 | ($error != null): true
19 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/negative-testing/resource/resources.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: good
5 | data:
6 | foo: bar
7 | ---
8 | apiVersion: v1
9 | kind: ConfigMap
10 | metadata:
11 | name: bad
12 | data:
13 | foo: true
14 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/negative-testing/script/README.md:
--------------------------------------------------------------------------------
1 | # Test: `negative-script`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `script` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/negative-testing/script/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: negative-script
6 | spec:
7 | steps:
8 | - try:
9 | - script:
10 | content: kubectl get foo
11 | check:
12 | ($error != null): true
13 | ($stderr): |
14 | error: the server doesn't have a resource type "foo"
15 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/non-resource-assertion/assert.yaml:
--------------------------------------------------------------------------------
1 | (x_k8s_list($client, 'v1', 'Node')):
2 | (length(items)): 1
3 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/non-resource-assertion/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: non-resource-assertion
6 | spec:
7 | steps:
8 | - try:
9 | - assert:
10 | file: assert.yaml
11 | - error:
12 | file: error.yaml
13 | - try:
14 | - assert:
15 | resource:
16 | (x_k8s_list($client, 'v1', 'Node')):
17 | (length(items)): 1
18 | - error:
19 | resource:
20 | (x_k8s_list($client, 'v1', 'Node')):
21 | (length(items)): 2
22 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/non-resource-assertion/error.yaml:
--------------------------------------------------------------------------------
1 | (x_k8s_list($client, 'v1', 'Node')):
2 | (length(items)): 2
3 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/orphan/README.md:
--------------------------------------------------------------------------------
1 | # Test: `delete-test`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [delete-test](#step-delete-test) | 0 | 5 | 0 | 0 | 0 |
10 |
11 | ### Step: `delete-test`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `sleep` | 0 | 0 | *No description* |
21 | | 3 | `delete` | 0 | 0 | *No description* |
22 | | 4 | `sleep` | 0 | 0 | *No description* |
23 | | 5 | `error` | 0 | 0 | *No description* |
24 |
25 | ---
26 |
27 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/patch/README.md:
--------------------------------------------------------------------------------
1 | # Test: `patch`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 3 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `patch` | 0 | 0 | *No description* |
21 | | 3 | `assert` | 0 | 0 | *No description* |
22 |
23 | ---
24 |
25 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/proxy/README.md:
--------------------------------------------------------------------------------
1 | # Test: `proxy`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `proxy` | 0 | 1 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/proxy/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: proxy
6 | spec:
7 | skip: true
8 | steps:
9 | - try:
10 | - proxy:
11 | apiVersion: v1
12 | kind: Service
13 | namespace: kyverno
14 | name: kyverno-svc-metrics
15 | port: metrics-port
16 | path: /metrics
17 | outputs:
18 | - name: metrics
19 | value: (x_metrics_decode($stdout))
20 | - assert:
21 | resource:
22 | ($metrics[?as_string(metric.code) == '500' && as_string(metric.__name__) == 'promhttp_metric_handler_requests_total'].value):
23 | - 0
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/quick-start/README.md:
--------------------------------------------------------------------------------
1 | # Test: `quick-start`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/quick-start/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: quick-start
6 | spec:
7 | steps:
8 | - try:
9 | # first operation: create the config map
10 | - apply:
11 | # file is relative to the test folder
12 | file: configmap.yaml
13 | # second operation: verify the config map exists and contains the expected data
14 | - assert:
15 | # file is relative to the test folder
16 | file: configmap.yaml
17 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/quick-start/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: chainsaw-quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/script-env/README.md:
--------------------------------------------------------------------------------
1 | # Test: `script-env`
2 |
3 | *No description*
4 |
5 | ## Bindings
6 |
7 | | # | Name | Value |
8 | |:-:|---|---|
9 | | 1 | `chainsaw` | "chainsaw" |
10 |
11 | ## Steps
12 |
13 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
14 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
15 | | 1 | [step-1](#step-step-1) | 1 | 2 | 0 | 0 | 0 |
16 |
17 | ### Step: `step-1`
18 |
19 | *No description*
20 |
21 | #### Bindings
22 |
23 | | # | Name | Value |
24 | |:-:|---|---|
25 | | 1 | `hello` | "hello" |
26 |
27 | #### Try
28 |
29 | | # | Operation | Bindings | Outputs | Description |
30 | |:-:|---|:-:|:-:|---|
31 | | 1 | `script` | 0 | 0 | *No description* |
32 | | 2 | `command` | 0 | 0 | *No description* |
33 |
34 | ---
35 |
36 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/sleep/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: sleep
6 | spec:
7 | steps:
8 | - try:
9 | - sleep:
10 | duration: 10s
11 | catch:
12 | - sleep:
13 | duration: 5s
14 | finally:
15 | - sleep:
16 | duration: 5s
17 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/step-template-bindings/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: step-template-bindings
6 | spec:
7 | steps:
8 | - use:
9 | template: template.yaml
10 | with:
11 | bindings:
12 | - name: input
13 | value: from-test
14 | - try:
15 | - assert:
16 | resource:
17 | apiVersion: v1
18 | kind: ConfigMap
19 | metadata:
20 | name: from-test
21 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/step-template-bindings/template.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/steptemplate-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: StepTemplate
4 | metadata:
5 | name: template
6 | spec:
7 | bindings:
8 | - name: input
9 | value: from-template
10 | try:
11 | - create:
12 | resource:
13 | apiVersion: v1
14 | kind: ConfigMap
15 | metadata:
16 | name: ($input)
17 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/step-template/README.md:
--------------------------------------------------------------------------------
1 | # Test: `quick-start`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 1 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Bindings
16 |
17 | | # | Name | Value |
18 | |:-:|---|---|
19 | | 1 | `file` | "configmap.yaml" |
20 |
21 | #### Try
22 |
23 | | # | Operation | Bindings | Outputs | Description |
24 | |:-:|---|:-:|:-:|---|
25 | | 1 | `apply` | 0 | 0 | *No description* |
26 | | 2 | `assert` | 0 | 0 | *No description* |
27 |
28 | ---
29 |
30 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/step-template/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: quick-start
6 | spec:
7 | steps:
8 | - use:
9 | template: step-template.yaml
10 | with:
11 | bindings:
12 | - name: file
13 | value: configmap.yaml
14 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/step-template/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: chainsaw-quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/step-template/step-template.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/steptemplate-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: StepTemplate
4 | metadata:
5 | name: quick-start
6 | spec:
7 | try:
8 | # first operation: create the config map
9 | - apply:
10 | # file is relative to the test folder
11 | file: ($file)
12 | # second operation: verify the config map exists and contains the expected data
13 | - assert:
14 | # file is relative to the test folder
15 | file: ($file)
16 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/template/README.md:
--------------------------------------------------------------------------------
1 | # Test: `template`
2 |
3 | *No description*
4 |
5 | ## Bindings
6 |
7 | | # | Name | Value |
8 | |:-:|---|---|
9 | | 1 | `foo` | "(join('-', [$namespace, 'foo']))" |
10 |
11 | ## Steps
12 |
13 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
14 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
15 | | 1 | [step-1](#step-step-1) | 0 | 3 | 0 | 0 | 0 |
16 |
17 | ### Step: `step-1`
18 |
19 | *No description*
20 |
21 | #### Try
22 |
23 | | # | Operation | Bindings | Outputs | Description |
24 | |:-:|---|:-:|:-:|---|
25 | | 1 | `apply` | 0 | 0 | *No description* |
26 | | 2 | `assert` | 0 | 0 | *No description* |
27 | | 3 | `delete` | 0 | 0 | *No description* |
28 |
29 | ---
30 |
31 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/test-info/README.md:
--------------------------------------------------------------------------------
1 | # Test: `test-info`
2 |
3 | *No description*
4 |
5 | ## Bindings
6 |
7 | | # | Name | Value |
8 | |:-:|---|---|
9 | | 1 | `foo` | "(join('-', [$test.metadata.name, 'foo']))" |
10 |
11 | ## Steps
12 |
13 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
14 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
15 | | 1 | [step-1](#step-step-1) | 0 | 2 | 0 | 0 | 0 |
16 |
17 | ### Step: `step-1`
18 |
19 | *No description*
20 |
21 | #### Try
22 |
23 | | # | Operation | Bindings | Outputs | Description |
24 | |:-:|---|:-:|:-:|---|
25 | | 1 | `script` | 0 | 1 | *No description* |
26 | | 2 | `assert` | 0 | 0 | *No description* |
27 |
28 | ---
29 |
30 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/test-info/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: test-info
6 | spec:
7 | bindings:
8 | - name: foo
9 | value: (join('-', [$test.metadata.name, 'foo']))
10 | steps:
11 | - try:
12 | - script:
13 | env:
14 | - name: FOO
15 | value: ($foo)
16 | outputs:
17 | - name: OUTPUT
18 | value: ($stdout)
19 | content: echo $FOO
20 | - assert:
21 | resource:
22 | (trim_space($OUTPUT)): test-info-foo
--------------------------------------------------------------------------------
/testdata/e2e/examples/timeout/README.md:
--------------------------------------------------------------------------------
1 | # Test: `timeout`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `script` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/timeout/chainsaw-test.yml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: timeout
6 | spec:
7 | steps:
8 | - try:
9 | - script:
10 | content: sleep 5
11 | timeout: 3s
12 | check:
13 | ($error != null): true
14 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/update-crd/README.md:
--------------------------------------------------------------------------------
1 | # Test: `update-crd`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 6 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 | | 3 | `apply` | 0 | 0 | *No description* |
22 | | 4 | `update` | 0 | 0 | *No description* |
23 | | 5 | `error` | 0 | 0 | *No description* |
24 | | 6 | `assert` | 0 | 0 | *No description* |
25 |
26 | ---
27 |
28 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/update/README.md:
--------------------------------------------------------------------------------
1 | # Test: `update`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 4 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `update` | 0 | 0 | *No description* |
21 | | 3 | `assert` | 0 | 0 | *No description* |
22 | | 4 | `error` | 0 | 0 | *No description* |
23 |
24 | ---
25 |
26 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/values/README.md:
--------------------------------------------------------------------------------
1 | # Test: `values`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [step-1](#step-step-1) | 0 | 1 | 0 | 0 | 0 |
10 |
11 | ### Step: `step-1`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `assert` | 0 | 0 | *No description* |
20 |
21 | ---
22 |
23 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/values/chainsaw-test.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../../../.schemas/json/test-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Test
4 | metadata:
5 | name: values
6 | spec:
7 | steps:
8 | - try:
9 | - assert:
10 | resource:
11 | ($values.foo): bar
12 |
--------------------------------------------------------------------------------
/testdata/e2e/examples/yaml-anchors/README.md:
--------------------------------------------------------------------------------
1 | # Test: `yaml-anchors`
2 |
3 | *No description*
4 |
5 | ## Steps
6 |
7 | | # | Name | Bindings | Try | Catch | Finally | Cleanup |
8 | |:-:|---|:-:|:-:|:-:|:-:|:-:|
9 | | 1 | [yaml-anchors](#step-yaml-anchors) | 0 | 2 | 0 | 0 | 0 |
10 |
11 | ### Step: `yaml-anchors`
12 |
13 | *No description*
14 |
15 | #### Try
16 |
17 | | # | Operation | Bindings | Outputs | Description |
18 | |:-:|---|:-:|:-:|---|
19 | | 1 | `apply` | 0 | 0 | *No description* |
20 | | 2 | `assert` | 0 | 0 | *No description* |
21 |
22 | ---
23 |
24 |
--------------------------------------------------------------------------------
/testdata/e2e/values.yaml:
--------------------------------------------------------------------------------
1 | foo: bar
--------------------------------------------------------------------------------
/testdata/kuttl/.chainsaw.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/configuration-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: Configuration
4 | metadata:
5 | creationTimestamp: null
6 | name: configuration
7 | spec:
8 | parallel: 4
9 | template: false
10 | timeouts:
11 | apply: 5m0s
12 | assert: 5m0s
13 | cleanup: 5m0s
14 | delete: 5m0s
15 | error: 5m0s
16 | exec: 5m0s
17 |
--------------------------------------------------------------------------------
/testdata/kuttl/01-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestAssert
3 | timeout: 30
4 | commands:
5 | - command: echo hello
6 | collectors:
7 | - type: pod
8 | pod: nginx
--------------------------------------------------------------------------------
/testdata/kuttl/01-step.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestStep
3 | delete:
4 | # Delete a Pod
5 | - apiVersion: v1
6 | kind: Pod
7 | name: my-pod
8 | # Delete all Pods with app=nginx
9 | - apiVersion: v1
10 | kind: Pod
11 | labels:
12 | app: nginx
13 | # Delete all Pods in the test namespace
14 | - apiVersion: v1
15 | kind: Pod
16 | commands:
17 | - script: echo "hello world"
18 | skipLogOutput: true
19 | - command: echo "hello world"
20 | skipLogOutput: true
21 |
--------------------------------------------------------------------------------
/testdata/kuttl/02-assert.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestAssert
3 | timeout: 30
4 | commands:
5 | - command: echo hello
6 | collectors:
7 | - type: command
8 | command: sleep 1
--------------------------------------------------------------------------------
/testdata/kuttl/02-step.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestStep
3 | delete:
4 | # Delete a Pod
5 | - apiVersion: v1
6 | kind: Pod
7 | name: my-pod
8 | # Delete all Pods with app=nginx
9 | - apiVersion: v1
10 | kind: Pod
11 | labels:
12 | app: nginx
13 | # Delete all Pods in the test namespace
14 | - apiVersion: v1
15 | kind: Pod
16 | commands:
17 | - script: echo "hello world"
18 | skipLogOutput: true
19 | - command: echo "hello world"
20 | skipLogOutput: true
21 |
--------------------------------------------------------------------------------
/testdata/kuttl/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: quick-start
5 | data:
6 | foo: bar
7 |
--------------------------------------------------------------------------------
/testdata/kuttl/invalid-config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestSuite
3 | data:
4 | foo: bar
5 |
--------------------------------------------------------------------------------
/testdata/kuttl/kuttl-test.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestSuite
3 | parallel: 4
4 | timeout: 300
5 | startControlPlane: true
--------------------------------------------------------------------------------
/testdata/kuttl/multiple-config.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kuttl.dev/v1beta1
2 | kind: TestSuite
3 | parallel: 4
4 | timeout: 300
5 | startControlPlane: true
6 | ---
7 | apiVersion: kuttl.dev/v1beta1
8 | kind: TestSuite
9 | parallel: 4
10 | timeout: 300
11 | startControlPlane: true
12 |
--------------------------------------------------------------------------------
/testdata/report/JUNIT-TEST.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/testdata/report/XML.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/testdata/resource/empty.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/resource/empty.yaml
--------------------------------------------------------------------------------
/testdata/resource/folder-invalid/invalid.yaml:
--------------------------------------------------------------------------------
1 | this: is
2 | a: invalid
3 |
--------------------------------------------------------------------------------
/testdata/resource/folder-valid/valid.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Pod
4 | metadata:
5 | name: test-pod
6 | ---
7 | apiVersion: v1
8 | kind: Service
9 | metadata:
10 | name: test-service
11 |
--------------------------------------------------------------------------------
/testdata/resource/invalid.yaml:
--------------------------------------------------------------------------------
1 | this: is
2 | a: invalid
3 |
--------------------------------------------------------------------------------
/testdata/resource/list.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - apiVersion: v1
5 | kind: ConfigMap
6 | metadata:
7 | name: cm-1
8 | namespace: default
9 | data:
10 | key: 'yes'
11 | - apiVersion: v1
12 | kind: ConfigMap
13 | metadata:
14 | name: cm-2
15 | namespace: default
16 | data:
17 | key: 'no'
18 |
--------------------------------------------------------------------------------
/testdata/resource/valid.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Pod
4 | metadata:
5 | name: test-pod
6 | ---
7 | apiVersion: v1
8 | kind: Service
9 | metadata:
10 | name: test-service
11 |
--------------------------------------------------------------------------------
/testdata/runner/processors/cron-job.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: batch/v1beta1
2 | kind: CronJob
3 | metadata:
4 | name: hello
5 | namespace: default
6 | spec:
7 | schedule: "*/1 * * * *"
8 | jobTemplate:
9 | spec:
10 | template:
11 | spec:
12 | containers:
13 | - name: hello
14 | image: busybox
15 | args: ['/bin/sh', '-c', 'date; echo Hello from the Chainsaw']
16 | restartPolicy: OnFailure
--------------------------------------------------------------------------------
/testdata/runner/processors/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: chainsaw
5 | spec:
6 | replicas: 1
7 | template:
8 | metadata:
9 | labels:
10 | editor: vscode
11 | spec:
12 | containers:
13 | - name: nginx
14 | image: nginx:1.7.9
--------------------------------------------------------------------------------
/testdata/runner/processors/pod.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: myapp
5 | labels:
6 | name: myapp
7 | spec:
8 | containers:
9 | - name: myapp
10 | image: myapp:latest
11 | resources:
12 | limits:
13 | memory: "128Mi"
14 | cpu: "500m"
15 |
--------------------------------------------------------------------------------
/testdata/step-template/bad-step.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../.schemas/json/steptemplate-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: StepTemplate
4 | metadata:
5 | name: quick-start
6 | spec:
7 | try:
8 | - foo: bar
--------------------------------------------------------------------------------
/testdata/step-template/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: default
5 | data:
6 | foo: bar
--------------------------------------------------------------------------------
/testdata/step-template/custom.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../.schemas/json/steptemplate-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: StepTemplate
4 | metadata:
5 | name: quick-start
6 | spec:
7 | try:
8 | # first operation: create the config map
9 | - apply:
10 | # file is relative to the test folder
11 | file: configmap.yaml
12 | # second operation: verify the config map exists and contains the expected data
13 | - assert:
14 | # file is relative to the test folder
15 | file: configmap.yaml
16 |
--------------------------------------------------------------------------------
/testdata/step-template/empty.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/step-template/empty.yaml
--------------------------------------------------------------------------------
/testdata/step-template/no-spec.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../.schemas/json/steptemplate-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: StepTemplate
4 | metadata:
5 | name: quick-start
6 |
--------------------------------------------------------------------------------
/testdata/step-template/no-try.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=../../.schemas/json/steptemplate-chainsaw-v1alpha1.json
2 | apiVersion: chainsaw.kyverno.io/v1alpha1
3 | kind: StepTemplate
4 | metadata:
5 | name: quick-start
6 | spec: {}
--------------------------------------------------------------------------------
/testdata/test/bad-step.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 | spec:
6 | steps:
7 | - foo: bar
--------------------------------------------------------------------------------
/testdata/test/configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: default
5 | data:
6 | foo: bar
--------------------------------------------------------------------------------
/testdata/test/empty.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/test/empty.yaml
--------------------------------------------------------------------------------
/testdata/test/multiple.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 | spec:
6 | steps: []
7 | ---
8 | apiVersion: chainsaw.kyverno.io/v1alpha1
9 | kind: Test
10 | metadata:
11 | name: test-2
12 | spec:
13 | steps: []
14 |
--------------------------------------------------------------------------------
/testdata/test/no-spec.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 |
--------------------------------------------------------------------------------
/testdata/test/no-steps.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 | spec: {}
--------------------------------------------------------------------------------
/testdata/test/ok.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 | spec:
6 | steps:
7 | - try:
8 | - apply:
9 | file: foo.yaml
10 | catch:
11 | - podLogs:
12 | namespace: foo
13 | name: bar
14 | - events:
15 | namespace: foo
16 | name: bar
17 | - command:
18 | entrypoint: time
19 | - script:
20 | content: echo "hello"
21 | - try:
22 | - assert:
23 | file: bar.yaml
24 | finally:
25 | - podLogs:
26 | namespace: foo
27 | name: bar
28 | - events:
29 | namespace: foo
30 | name: bar
31 | - command:
32 | entrypoint: time
33 | - script:
34 | content: echo "hello"
35 |
--------------------------------------------------------------------------------
/testdata/test/raw-resource.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: chainsaw.kyverno.io/v1alpha1
2 | kind: Test
3 | metadata:
4 | name: test-1
5 | spec:
6 | steps:
7 | - try:
8 | - apply:
9 | resource:
10 | apiVersion: v1
11 | kind: ConfigMap
12 | metadata:
13 | name: chainsaw-quick-start
14 | data:
15 | foo: bar
16 | - try:
17 | - create:
18 | resource:
19 | apiVersion: v1
20 | kind: ConfigMap
21 | metadata:
22 | name: chainsaw-quick-start
23 | data:
24 | foo: bar
25 |
--------------------------------------------------------------------------------
/testdata/validation/example-file.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: nginx
5 | labels:
6 | name: nginx
7 | spec:
8 | containers:
9 | - name: nginx
10 | image: nginx
11 | resources:
12 | limits:
13 | memory: "128Mi"
14 | cpu: "500m"
15 |
--------------------------------------------------------------------------------
/testdata/values/empty.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/testdata/values/empty.yaml
--------------------------------------------------------------------------------
/testdata/values/invalid.yaml:
--------------------------------------------------------------------------------
1 | this, or that
--------------------------------------------------------------------------------
/testdata/values/values-1.yaml:
--------------------------------------------------------------------------------
1 | foo:
2 | bar: baz
3 | test: 42
--------------------------------------------------------------------------------
/testdata/values/values-2.yaml:
--------------------------------------------------------------------------------
1 | foo:
2 | bar: baz
3 | test: ~
--------------------------------------------------------------------------------
/website/docs/configuration/options/label-selectors.md:
--------------------------------------------------------------------------------
1 | # Label selectors
2 |
3 | Chainsaw can filter the tests to run using [label selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors).
4 |
5 | ## Configuration
6 |
7 | ### With file
8 |
9 | !!! note
10 | Label selectors can't be configured with a configuration file.
11 |
12 | ### With flags
13 |
14 | ```bash
15 | chainsaw test --selector foo=bar
16 | ```
17 |
--------------------------------------------------------------------------------
/website/docs/configuration/options/no-cluster.md:
--------------------------------------------------------------------------------
1 | # No cluster options
2 |
3 | Chainsaw can be run without any connection to a Kubernetes cluster.
4 |
5 | In this case, Chainsaw will not try to create an ephemeral namespace and all operations requiring a Kubernetes cluster will fail.
6 |
7 | ## Configuration
8 |
9 | ### With file
10 |
11 | !!! note
12 | No cluster options can't be configured with a configuration file.
13 |
14 | ### With flags
15 |
16 | ```bash
17 | chainsaw test --no-cluster
18 | ```
19 |
--------------------------------------------------------------------------------
/website/docs/configuration/options/pause.md:
--------------------------------------------------------------------------------
1 | # Pause options
2 |
3 | Chainsaw can be configured to pause and wait for user input when a failure happens.
4 | This is useful when Chainsaw is run locally to allow debugging and troubleshooting failures.
5 |
6 | ## Configuration
7 |
8 | ### With file
9 |
10 | !!! note
11 | Pause options can't be configured with a configuration file.
12 |
13 | ### With flags
14 |
15 | ```bash
16 | chainsaw test --pause-on-failure
17 | ```
18 |
--------------------------------------------------------------------------------
/website/docs/configuration/options/values.md:
--------------------------------------------------------------------------------
1 | # External values
2 |
3 | Chainsaw can pass arbitrary values when running tests using the `--values` flag.
4 | Values will be available to tests under the `$values` binding.
5 |
6 | ## Configuration
7 |
8 | ### With file
9 |
10 | !!! note
11 | Values can't be configured with a configuration file.
12 |
13 | ### With flags
14 |
15 | ```bash
16 | chainsaw test --values ./values.yaml
17 | ```
18 |
--------------------------------------------------------------------------------
/website/docs/examples/concurrency.md:
--------------------------------------------------------------------------------
1 | # Concurrency control
2 |
3 | By default, Chainsaw will run tests in parallel.
4 |
5 | The number of concurrent tests can be configured globally using a [configuration file](http://127.0.0.1:8000/chainsaw/configuration/options/execution/) or with the `--parallel` flag.
6 |
7 | Alternatively, the concurrent nature of a test can specified at the test level:
8 |
9 | ```yaml
10 | apiVersion: chainsaw.kyverno.io/v1alpha1
11 | kind: Test
12 | metadata:
13 | name: example
14 | spec:
15 | # concurrency can be specified per test (`true` or `false`)
16 | # default value is `true`
17 | concurrent: false
18 | # ...
19 | ```
20 |
21 | All non-concurrent tests are executed first, followed by the concurrent tests running in parallel.
22 |
--------------------------------------------------------------------------------
/website/docs/examples/events.md:
--------------------------------------------------------------------------------
1 | # Work with events
2 |
3 | Kubernetes events are regular Kubernetes objects and can be asserted on just like any other object:
4 |
5 | ```yaml
6 | apiVersion: chainsaw.kyverno.io/v1alpha1
7 | kind: Test
8 | metadata:
9 | name: example
10 | spec:
11 | steps:
12 | - try:
13 | - assert:
14 | resource:
15 | apiVersion: v1
16 | kind: Event
17 | reason: Started
18 | source:
19 | component: kubelet
20 | involvedObject:
21 | apiVersion: v1
22 | kind: Pod
23 | name: my-pod
24 | ```
25 |
--------------------------------------------------------------------------------
/website/docs/examples/index.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | !!! info
4 | Select an item in the navigation menu to browse a specific page.
5 |
--------------------------------------------------------------------------------
/website/docs/examples/label-selectors.md:
--------------------------------------------------------------------------------
1 | # Work with label selectors
2 |
3 | Chainsaw can filter the tests to run using [label selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors).
4 |
5 | You can pass label selectors using the `--selector` flag when invoking the `chainsaw test` command.
6 |
7 | Given the test below:
8 |
9 | ```yaml
10 | apiVersion: chainsaw.kyverno.io/v1alpha1
11 | kind: Test
12 | metadata:
13 | name: basic
14 | labels:
15 | foo: bar
16 | spec:
17 | # ...
18 | ```
19 |
20 | Invoking Chainsaw with the command below will take the test above into account:
21 |
22 | ```bash
23 | chainsaw test --selector foo=bar
24 | ```
25 |
--------------------------------------------------------------------------------
/website/docs/guides/lint.md:
--------------------------------------------------------------------------------
1 | # Lint tests
2 |
3 | ## Overview
4 |
5 | Chainsaw comes with a `lint` command to detect ill-formated tests.
6 |
7 | !!! tip "Reference documentation"
8 |
9 | You can view the full command documentation [here](../reference/commands/chainsaw_lint.md).
10 |
11 | ## Usage
12 |
13 | To build the docs of a test, Chainsaw provides the `chainsaw lint test -f path/to/chainsaw-test.yaml` command.
14 |
15 | ```bash
16 | chainsaw lint test -f - < error
23 | ```
24 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/lookup.md:
--------------------------------------------------------------------------------
1 | # lookup
2 |
3 | ## Signature
4 |
5 | `lookup(object|array, string|number)`
6 |
7 | ## Description
8 |
9 | Returns the value corresponding to the given key/index in the given object/array.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/lower.md:
--------------------------------------------------------------------------------
1 | # lower
2 |
3 | ## Signature
4 |
5 | `lower(string)`
6 |
7 | ## Description
8 |
9 | Returns the given string with all Unicode letters mapped to their lower case.
10 |
11 | ## Examples
12 |
13 | ```
14 | lower('FOOBAR') == 'foobar'
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/map.md:
--------------------------------------------------------------------------------
1 | # map
2 |
3 | ## Signature
4 |
5 | `map(expref, array)`
6 |
7 | ## Description
8 |
9 | Transforms elements in a given array and returns the result.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/max.md:
--------------------------------------------------------------------------------
1 | # max
2 |
3 | ## Signature
4 |
5 | `max(array[number]|array[string])`
6 |
7 | ## Description
8 |
9 | Returns the highest found element in the provided array argument. An empty array will produce a return value of null.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/max_by.md:
--------------------------------------------------------------------------------
1 | # max_by
2 |
3 | ## Signature
4 |
5 | `max_by(array, expref)`
6 |
7 | ## Description
8 |
9 | Returns the highest found element using a custom expression to compute the associated value for each element in the input array.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/merge.md:
--------------------------------------------------------------------------------
1 | # merge
2 |
3 | ## Signature
4 |
5 | `merge(object)`
6 |
7 | ## Description
8 |
9 | Meges a list of objects together and returns the result.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/min.md:
--------------------------------------------------------------------------------
1 | # min
2 |
3 | ## Signature
4 |
5 | `min(array[number]|array[string])`
6 |
7 | ## Description
8 |
9 | Returns the lowest found element in the provided array argument.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/min_by.md:
--------------------------------------------------------------------------------
1 | # min_by
2 |
3 | ## Signature
4 |
5 | `min_by(array, expref)`
6 |
7 | ## Description
8 |
9 | Returns the lowest found element using a custom expression to compute the associated value for each element in the input array.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/modulo.md:
--------------------------------------------------------------------------------
1 | # modulo
2 |
3 | ## Signature
4 |
5 | `modulo(any, any)`
6 |
7 | ## Description
8 |
9 | Divisor must be non-zero, arguments must be integers.
10 |
11 | ## Examples
12 |
13 | ```
14 | modulo(`10`, `3`) == `1`
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/multiply.md:
--------------------------------------------------------------------------------
1 | # multiply
2 |
3 | ## Signature
4 |
5 | `multiply(any, any)`
6 |
7 | ## Description
8 |
9 | Does arithmetic multiplication of two specified values of numbers, quantities, and durations.
10 |
11 | ## Examples
12 |
13 | ### With numbers
14 |
15 | ```
16 | multiply(`1`, `2`) == `2`
17 | ```
18 |
19 | ### With durations
20 |
21 | ```
22 | multiply('1h', `2`) == '2h'
23 | ```
24 |
25 | ### With quantities
26 |
27 | ```
28 | multiply('1Mi', `2`) == '2Mi'
29 | ```
30 |
31 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/not_null.md:
--------------------------------------------------------------------------------
1 | # not_null
2 |
3 | ## Signature
4 |
5 | `not_null(any)`
6 |
7 | ## Description
8 |
9 | Returns the first non null element in the input array.
10 |
11 | ## Examples
12 |
13 | ```
14 | not_null(null, null, 'foo') == 'foo'
15 | ```
16 |
17 | ```
18 | not_null(null, null) == null
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/object_from_lists.md:
--------------------------------------------------------------------------------
1 | # object_from_lists
2 |
3 | ## Signature
4 |
5 | `object_from_lists(array, array)`
6 |
7 | ## Description
8 |
9 | Converts a pair of lists containing keys and values to an object.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/pad_left.md:
--------------------------------------------------------------------------------
1 | # pad_left
2 |
3 | ## Signature
4 |
5 | `pad_left(string, number, string)`
6 |
7 | ## Description
8 |
9 | Adds characters to the beginning of a string.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/pad_right.md:
--------------------------------------------------------------------------------
1 | # pad_right
2 |
3 | ## Signature
4 |
5 | `pad_right(string, number, string)`
6 |
7 | ## Description
8 |
9 | Adds characters to the end of a string.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/parse_json.md:
--------------------------------------------------------------------------------
1 | # parse_json
2 |
3 | ## Signature
4 |
5 | `parse_json(string)`
6 |
7 | ## Description
8 |
9 | Decodes a valid JSON encoded string to the appropriate type. Opposite of `to_string` function.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/parse_yaml.md:
--------------------------------------------------------------------------------
1 | # parse_yaml
2 |
3 | ## Signature
4 |
5 | `parse_yaml(string)`
6 |
7 | ## Description
8 |
9 | Decodes a valid YAML encoded string to the appropriate type provided it can be represented as JSON.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/path_canonicalize.md:
--------------------------------------------------------------------------------
1 | # path_canonicalize
2 |
3 | ## Signature
4 |
5 | `path_canonicalize(string)`
6 |
7 | ## Description
8 |
9 | Normalizes or canonicalizes a given path by removing excess slashes.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/pattern_match.md:
--------------------------------------------------------------------------------
1 | # pattern_match
2 |
3 | ## Signature
4 |
5 | `pattern_match(string, string|number)`
6 |
7 | ## Description
8 |
9 | '*' matches zero or more alphanumeric characters, '?' matches a single alphanumeric character.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/random.md:
--------------------------------------------------------------------------------
1 | # random
2 |
3 | ## Signature
4 |
5 | `random(string)`
6 |
7 | ## Description
8 |
9 | Generates a random sequence of characters.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/regex_match.md:
--------------------------------------------------------------------------------
1 | # regex_match
2 |
3 | ## Signature
4 |
5 | `regex_match(string, string|number)`
6 |
7 | ## Description
8 |
9 | First string is the regular exression which is compared with second input which can be a number or string.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/regex_replace_all.md:
--------------------------------------------------------------------------------
1 | # regex_replace_all
2 |
3 | ## Signature
4 |
5 | `regex_replace_all(string, string|number, string|number)`
6 |
7 | ## Description
8 |
9 | Converts all parameters to string.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/regex_replace_all_literal.md:
--------------------------------------------------------------------------------
1 | # regex_replace_all_literal
2 |
3 | ## Signature
4 |
5 | `regex_replace_all_literal(string, string|number, string|number)`
6 |
7 | ## Description
8 |
9 | Converts all parameters to string.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/replace.md:
--------------------------------------------------------------------------------
1 | # replace
2 |
3 | ## Signature
4 |
5 | `replace(string, string, string, number)`
6 |
7 | ## Description
8 |
9 | Replaces a specified number of instances of the source string with the replacement string in a parent.
10 |
11 | ## Examples
12 |
13 | ```
14 | replace('foobar', 'oo', 'ii') == 'fiibar'
15 | ```
16 |
17 | ```
18 | replace('foobar', 'o', 'i', `1`) == 'fiobar'
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/replace_all.md:
--------------------------------------------------------------------------------
1 | # replace_all
2 |
3 | ## Signature
4 |
5 | `replace_all(string, string, string)`
6 |
7 | ## Description
8 |
9 | Replace all instances of one string with another in an overall parent string.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/reverse.md:
--------------------------------------------------------------------------------
1 | # reverse
2 |
3 | ## Signature
4 |
5 | `reverse(array|string)`
6 |
7 | ## Description
8 |
9 | Reverses the input string or array and returns the result.
10 |
11 | ## Examples
12 |
13 | ```
14 | reverse('abcd') == 'dcba'
15 | ```
16 |
17 | ```
18 | reverse([`1`, `2`, `3`, `4`]) == [`4`, `3`, `2`, `1`]
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/round.md:
--------------------------------------------------------------------------------
1 | # round
2 |
3 | ## Signature
4 |
5 | `round(number, number)`
6 |
7 | ## Description
8 |
9 | Does roundoff to upto the given decimal places.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/semver_compare.md:
--------------------------------------------------------------------------------
1 | # semver_compare
2 |
3 | ## Signature
4 |
5 | `semver_compare(string, string)`
6 |
7 | ## Description
8 |
9 | Compares two strings which comply with the semantic versioning schema and outputs a boolean response as to the position of the second relative to the first.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/sort.md:
--------------------------------------------------------------------------------
1 | # sort
2 |
3 | ## Signature
4 |
5 | `sort(array[string]|array[number])`
6 |
7 | ## Description
8 |
9 | This function accepts an array argument and returns the sorted elements as an array.
10 |
11 | ## Examples
12 |
13 | ```
14 | sort(['b', 'a', 'c']) == ['a', 'b', 'c']
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/sort_by.md:
--------------------------------------------------------------------------------
1 | # sort_by
2 |
3 | ## Signature
4 |
5 | `sort_by(array, expref)`
6 |
7 | ## Description
8 |
9 | This function accepts an array argument and returns the sorted elements as an array using a custom expression to compute the associated value for each element.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/split.md:
--------------------------------------------------------------------------------
1 | # split
2 |
3 | ## Signature
4 |
5 | `split(string, string)`
6 |
7 | ## Description
8 |
9 | Splits the first string when the second string is found and converts it into an array.
10 |
11 | ## Examples
12 |
13 | ```
14 | split('average|-|min|-|max|-|mean|-|median', '|-|', `3`) == ['average', 'min', 'max', 'mean|-|median']
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/starts_with.md:
--------------------------------------------------------------------------------
1 | # starts_with
2 |
3 | ## Signature
4 |
5 | `starts_with(string, string)`
6 |
7 | ## Description
8 |
9 | Reports whether the input string begins with the provided string prefix argument.
10 |
11 | ## Examples
12 |
13 | ```
14 | starts_with('foobar', 'foo') == `true`
15 | ```
16 |
17 | ```
18 | starts_with('foobar', 'bar') == `false`
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/subtract.md:
--------------------------------------------------------------------------------
1 | # subtract
2 |
3 | ## Signature
4 |
5 | `subtract(any, any)`
6 |
7 | ## Description
8 |
9 | Does arithmetic subtraction of two specified values of numbers, quantities, and durations.
10 |
11 | ## Examples
12 |
13 | ### With numbers
14 |
15 | ```
16 | subtract(`2`, `1`) == `1`
17 | ```
18 |
19 | ### With durations
20 |
21 | ```
22 | subtract('2h', '1h') == '1h'
23 | ```
24 |
25 | ### With quantities
26 |
27 | ```
28 | subtract('2Mi', '1Mi') == '1Mi'
29 | ```
30 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/sum.md:
--------------------------------------------------------------------------------
1 | # sum
2 |
3 | ## Signature
4 |
5 | `sum(array)`
6 |
7 | ## Description
8 |
9 | Does arithmetic addition of specified array of values of numbers, quantities, and durations.
10 |
11 | ## Examples
12 |
13 | ```
14 | sum(`[]`) == `0`
15 | ```
16 |
17 | ```
18 | sum([`10`, `15`]) == `25`
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_add.md:
--------------------------------------------------------------------------------
1 | # time_add
2 |
3 | ## Signature
4 |
5 | `time_add(string, string)`
6 |
7 | ## Description
8 |
9 | Adds duration (second string) to a time value (first string).
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_after.md:
--------------------------------------------------------------------------------
1 | # time_after
2 |
3 | ## Signature
4 |
5 | `time_after(string, string)`
6 |
7 | ## Description
8 |
9 | Checks if a time is after another time, both in RFC3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_before.md:
--------------------------------------------------------------------------------
1 | # time_before
2 |
3 | ## Signature
4 |
5 | `time_before(string, string)`
6 |
7 | ## Description
8 |
9 | Checks if a time is before another time, both in RFC3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_between.md:
--------------------------------------------------------------------------------
1 | # time_between
2 |
3 | ## Signature
4 |
5 | `time_between(string, string, string)`
6 |
7 | ## Description
8 |
9 | Checks if a time is between a start and end time, all in RFC3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_diff.md:
--------------------------------------------------------------------------------
1 | # time_diff
2 |
3 | ## Signature
4 |
5 | `time_diff(string, string)`
6 |
7 | ## Description
8 |
9 | Calculate the difference between a start and end date in RFC3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_now.md:
--------------------------------------------------------------------------------
1 | # time_now
2 |
3 | ## Signature
4 |
5 | `time_now()`
6 |
7 | ## Description
8 |
9 | Returns current time in RFC 3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_now_utc.md:
--------------------------------------------------------------------------------
1 | # time_now_utc
2 |
3 | ## Signature
4 |
5 | `time_now_utc()`
6 |
7 | ## Description
8 |
9 | Returns current UTC time in RFC 3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_parse.md:
--------------------------------------------------------------------------------
1 | # time_parse
2 |
3 | ## Signature
4 |
5 | `time_parse(string, string)`
6 |
7 | ## Description
8 |
9 | Changes a time value of a given layout to RFC 3339.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_since.md:
--------------------------------------------------------------------------------
1 | # time_since
2 |
3 | ## Signature
4 |
5 | `time_since(string, string, string)`
6 |
7 | ## Description
8 |
9 | Calculate the difference between a start and end period of time where the end may either be a static definition or the then-current time.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_to_cron.md:
--------------------------------------------------------------------------------
1 | # time_to_cron
2 |
3 | ## Signature
4 |
5 | `time_to_cron(string)`
6 |
7 | ## Description
8 |
9 | Converts a time (RFC 3339) to a cron expression (string).
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_truncate.md:
--------------------------------------------------------------------------------
1 | # time_truncate
2 |
3 | ## Signature
4 |
5 | `time_truncate(string, string)`
6 |
7 | ## Description
8 |
9 | Returns the result of rounding time down to a multiple of duration.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/time_utc.md:
--------------------------------------------------------------------------------
1 | # time_utc
2 |
3 | ## Signature
4 |
5 | `time_utc(string)`
6 |
7 | ## Description
8 |
9 | Calcutes time in UTC from a given time in RFC 3339 format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/to_array.md:
--------------------------------------------------------------------------------
1 | # to_array
2 |
3 | ## Signature
4 |
5 | `to_array(any)`
6 |
7 | ## Description
8 |
9 | Returns a one element array containing the passed in argument, or the passed in value if it's an array.
10 |
11 | ## Examples
12 |
13 | ```
14 | to_array(`true`) == [`true`]
15 | ```
16 |
17 | ```
18 | to_array([`10`, `15`, `20`]) == [`10`, `15`, `20`]
19 | ```
20 |
21 | ```
22 | to_array(`[]`) == []
23 | ```
24 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/to_boolean.md:
--------------------------------------------------------------------------------
1 | # to_boolean
2 |
3 | ## Signature
4 |
5 | `to_boolean(string)`
6 |
7 | ## Description
8 |
9 | It returns true or false for any string, such as 'True', 'TruE', 'False', 'FAlse', 'faLSE', etc.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/to_lower.md:
--------------------------------------------------------------------------------
1 | # to_lower
2 |
3 | ## Signature
4 |
5 | `to_lower(string)`
6 |
7 | ## Description
8 |
9 | Takes in a string and outputs the same string with all lower-case letters.
10 |
11 | ## Examples
12 |
13 | ```
14 | lower('FOOBAR') == 'foobar'
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/to_number.md:
--------------------------------------------------------------------------------
1 | # to_number
2 |
3 | ## Signature
4 |
5 | `to_number(any)`
6 |
7 | ## Description
8 |
9 | Returns the parsed number.
10 |
11 | ## Examples
12 |
13 | ```
14 | to_number('1.0') == `1`
15 | ```
16 |
17 | ```
18 | to_number(`1.0`) == `1`
19 | ```
20 |
21 | ```
22 | to_number(`false`) == null
23 | ```
24 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/to_string.md:
--------------------------------------------------------------------------------
1 | # to_string
2 |
3 | ## Signature
4 |
5 | `to_string(any)`
6 |
7 | ## Description
8 |
9 | The JSON encoded value of the given argument.
10 |
11 | ## Examples
12 |
13 | ```
14 | to_string(`2`) == '2'
15 | ```
16 |
17 | ```
18 | to_string('foobar') == 'foobar'
19 | ```
20 |
21 | ```
22 | to_string(null) == 'null'
23 | ```
24 |
25 | ```
26 | to_string({bar:'bam',foo:'baz'}) == '{"bar":"bam","foo":"baz"}'
27 | ```
28 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/to_upper.md:
--------------------------------------------------------------------------------
1 | # to_upper
2 |
3 | ## Signature
4 |
5 | `to_upper(string)`
6 |
7 | ## Description
8 |
9 | Takes in a string and outputs the same string with all upper-case letters.
10 |
11 | ## Examples
12 |
13 | ```
14 | upper('foobar') == 'FOOBAR'
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/trim.md:
--------------------------------------------------------------------------------
1 | # trim
2 |
3 | ## Signature
4 |
5 | `trim(string, string)`
6 |
7 | ## Description
8 |
9 | Trims both ends of the source string by characters appearing in the second string.
10 |
11 | ## Examples
12 |
13 | ```
14 | trim(' foobar ', 'fbr ') == 'ooba'
15 | ```
16 |
17 | ```
18 | trim(' foobar ', 'fbr') == ' foobar '
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/trim_left.md:
--------------------------------------------------------------------------------
1 | # trim_left
2 |
3 | ## Signature
4 |
5 | `trim_left(string, string)`
6 |
7 | ## Description
8 |
9 | Removes the leading characters found in the passed in string argument.
10 |
11 | ## Examples
12 |
13 | ```
14 | trim_left(' foobar ', 'fbr ') == 'oobar '
15 | ```
16 |
17 | ```
18 | trim_left(' foobar ', 'fbr') == ' foobar '
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/trim_prefix.md:
--------------------------------------------------------------------------------
1 | # trim_prefix
2 |
3 | ## Signature
4 |
5 | `trim_prefix(string, string)`
6 |
7 | ## Description
8 |
9 | Trims the second string prefix from the first string if the first string starts with the prefix.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/trim_right.md:
--------------------------------------------------------------------------------
1 | # trim_right
2 |
3 | ## Signature
4 |
5 | `trim_right(string, string)`
6 |
7 | ## Description
8 |
9 | Removes the trailing characters found in the passed in string argument.
10 |
11 | ## Examples
12 |
13 | ```
14 | trim_right(' foobar ', 'fbr ') == ' fooba'
15 | ```
16 |
17 | ```
18 | trim_right(' foobar ', 'fbr') == ' foobar '
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/trim_space.md:
--------------------------------------------------------------------------------
1 | # trim_space
2 |
3 | ## Signature
4 |
5 | `trim_space(string)`
6 |
7 | ## Description
8 |
9 | Trims leading and trailing spaces from the string passed in argument.
10 |
11 | ## Examples
12 |
13 | ```
14 | trim_space(' foobar ') == 'foobar'
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/truncate.md:
--------------------------------------------------------------------------------
1 | # truncate
2 |
3 | ## Signature
4 |
5 | `truncate(string, number)`
6 |
7 | ## Description
8 |
9 | Length argument must be enclosed in backticks; ex. "{{request.object.metadata.name | truncate(@, `9`)}}".
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/type.md:
--------------------------------------------------------------------------------
1 | # type
2 |
3 | ## Signature
4 |
5 | `type(any)`
6 |
7 | ## Description
8 |
9 | Returns the JavaScript type of the given argument as a string value.
10 |
11 | ## Examples
12 |
13 | ```
14 | type(`false`) == 'boolean'
15 | ```
16 |
17 | ```
18 | type(null) == 'null'
19 | ```
20 |
21 | ```
22 | type('foobar') == 'string'
23 | ```
24 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/upper.md:
--------------------------------------------------------------------------------
1 | # upper
2 |
3 | ## Signature
4 |
5 | `upper(string)`
6 |
7 | ## Description
8 |
9 | Returns the given string with all Unicode letters mapped to their upper case.
10 |
11 | ## Examples
12 |
13 | ```
14 | upper('foobar') == 'FOOBAR'
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/values.md:
--------------------------------------------------------------------------------
1 | # values
2 |
3 | ## Signature
4 |
5 | `values(object)`
6 |
7 | ## Description
8 |
9 | Returns the values of the provided object.
10 |
11 | ## Examples
12 |
13 | ```
14 | values({bar:'bam',foo:'baz'}) == ['bam','baz']
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/wildcard.md:
--------------------------------------------------------------------------------
1 | # wildcard
2 |
3 | ## Signature
4 |
5 | `wildcard(string, string)`
6 |
7 | ## Description
8 |
9 | Compares a wildcard pattern with a given string and returns if they match or not.
10 |
11 | ## Examples
12 |
13 | ```
14 | wildcard('foo*', 'foobar') == `true`
15 | ```
16 |
17 | ```
18 | wildcard('fooba?', 'foobar') == `true`
19 | ```
20 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x509_decode.md:
--------------------------------------------------------------------------------
1 | # x509_decode
2 |
3 | ## Signature
4 |
5 | `x509_decode(string)`
6 |
7 | ## Description
8 |
9 | Decodes an x.509 certificate to an object. you may also use this in conjunction with `base64_decode` jmespath function to decode a base64-encoded certificate.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x_k8s_exists.md:
--------------------------------------------------------------------------------
1 | # x_k8s_exists
2 |
3 | ## Signature
4 |
5 | `x_k8s_exists(any, string, string, string, string)`
6 |
7 | ## Description
8 |
9 | Checks if a given resource exists in a Kubernetes cluster.
10 |
11 | ## Examples
12 |
13 | !!! info "Clustered resources"
14 |
15 | For clustered resources, you can leave the namespace empty `''`.
16 |
17 | ```
18 | # `$client` is a binding pointing to a Kubernetes client
19 |
20 | x_k8s_exists($client, 'apps/v1', 'Deployment', 'crossplane-system', 'crossplane')
21 | ```
22 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x_k8s_get.md:
--------------------------------------------------------------------------------
1 | # x_k8s_get
2 |
3 | ## Signature
4 |
5 | `x_k8s_get(any, string, string, string, string)`
6 |
7 | ## Description
8 |
9 | Gets a resource from a Kubernetes cluster.
10 |
11 | ## Examples
12 |
13 | !!! info "Clustered resources"
14 |
15 | For clustered resources, you can leave the namespace empty `''`.
16 |
17 | ```
18 | # `$client` is a binding pointing to a Kubernetes client
19 |
20 | x_k8s_get($client, 'apps/v1', 'Deployment', 'crossplane-system', 'crossplane')
21 | ```
22 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x_k8s_list.md:
--------------------------------------------------------------------------------
1 | # x_k8s_list
2 |
3 | ## Signature
4 |
5 | `x_k8s_list(any, string, string, string)`
6 |
7 | ## Description
8 |
9 | Lists resources from a Kubernetes cluster.
10 |
11 | ## Examples
12 |
13 | !!! info "Clustered resources"
14 |
15 | For clustered resources, you can leave the namespace empty `''`.
16 |
17 | ```
18 | # `$client` is a binding pointing to a Kubernetes client
19 |
20 | x_k8s_list($client, 'apps/v1', 'Deployment', 'crossplane-system')
21 | ```
22 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x_k8s_resource_exists.md:
--------------------------------------------------------------------------------
1 | # x_k8s_resource_exists
2 |
3 | ## Signature
4 |
5 | `x_k8s_resource_exists(any, string, string)`
6 |
7 | ## Description
8 |
9 | Checks if a given resource type is available in a Kubernetes cluster.
10 |
11 | ## Examples
12 |
13 | !!! info "Clustered resources"
14 |
15 | For clustered resources, you can leave the namespace empty `''`.
16 |
17 | ```
18 | # `$client` is a binding pointing to a Kubernetes client
19 |
20 | x_k8s_resource_exists($client, 'apps/v1', 'Deployment')
21 | ```
22 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x_k8s_server_version.md:
--------------------------------------------------------------------------------
1 | # x_k8s_server_version
2 |
3 | ## Signature
4 |
5 | `x_k8s_server_version(any)`
6 |
7 | ## Description
8 |
9 | Returns the version of a Kubernetes cluster.
10 |
11 | ## Examples
12 |
13 | ```
14 | # `$client` is a binding pointing to a Kubernetes client
15 |
16 | x_k8s_server_version($client)
17 | ```
18 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/x_metrics_decode.md:
--------------------------------------------------------------------------------
1 | # x_metrics_decode
2 |
3 | ## Signature
4 |
5 | `x_metrics_decode(string)`
6 |
7 | ## Description
8 |
9 | Decodes metrics in the Prometheus text format.
10 |
11 | ## Examples
12 |
13 | TODO
14 |
--------------------------------------------------------------------------------
/website/docs/reference/jp/examples/zip.md:
--------------------------------------------------------------------------------
1 | # zip
2 |
3 | ## Signature
4 |
5 | `zip(array, array)`
6 |
7 | ## Description
8 |
9 | Accepts one or more arrays as arguments and returns an array of arrays in which the i-th array contains the i-th element from each of the argument arrays. The returned array is truncated to the length of the shortest argument array.
10 |
11 | ## Examples
12 |
13 | ```
14 | zip(['a', 'b'], [`1`, `2`]) == [['a', `1`], ['b', `2`]]
15 | ```
16 |
--------------------------------------------------------------------------------
/website/docs/static/extra.css:
--------------------------------------------------------------------------------
1 | body>header>nav>a>img {
2 | border-radius: 10%;
3 | border: 1px solid #555;
4 | }
5 |
6 | td:nth-child(1) {
7 | text-wrap: nowrap;
8 | }
--------------------------------------------------------------------------------
/website/docs/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/website/docs/static/favicon.ico
--------------------------------------------------------------------------------
/website/docs/static/kyverno-chainsaw-horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/website/docs/static/kyverno-chainsaw-horizontal.png
--------------------------------------------------------------------------------
/website/docs/static/kyverno-chainsaw-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyverno/chainsaw/bab727ee05720d9d54ea7467f3597ef30717bc86/website/docs/static/kyverno-chainsaw-logo.png
--------------------------------------------------------------------------------
/website/docs/step/try.md:
--------------------------------------------------------------------------------
1 | # try
2 |
3 | A `try` statement is a sequence of [operations](../operations/index.md) executed in the same order they are declared.
4 | If an operation fails the entire step is considered failed.
5 |
6 | ## Operations
7 |
8 | A `try` statement supports all [operations](../operations/index.md):
9 |
10 | - [Apply](../operations/apply.md)
11 | - [Assert](../operations/assert.md)
12 | - [Command](../operations/command.md)
13 | - [Create](../operations/create.md)
14 | - [Delete](../operations/delete.md)
15 | - [Error](../operations/error.md)
16 | - [Patch](../operations/patch.md)
17 | - [Script](../operations/script.md)
18 | - [Sleep](../operations/sleep.md)
19 | - [Update](../operations/update.md)
20 | - [Wait](../operations/helpers/wait.md)
21 |
--------------------------------------------------------------------------------
/website/jp/examples/abs.md:
--------------------------------------------------------------------------------
1 | ```
2 | abs(`-1`) == `1`
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/add.md:
--------------------------------------------------------------------------------
1 | ### With numbers
2 |
3 | ```
4 | add(`1`, `2`) == `3`
5 | ```
6 |
7 | ### With durations
8 |
9 | ```
10 | add('1h', '2h') == '3h'
11 | ```
12 |
13 | ### With quantities
14 |
15 | ```
16 | add('1Mi', '2Mi') == '3Mi'
17 | ```
18 |
--------------------------------------------------------------------------------
/website/jp/examples/as_string.md:
--------------------------------------------------------------------------------
1 | ```
2 | as_string('foobar') == 'foobar'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/at.md:
--------------------------------------------------------------------------------
1 | ```
2 | at([`10`,`15`,`20`], `1`) == `15`
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/avg.md:
--------------------------------------------------------------------------------
1 | ```
2 | avg([`10`,`15`,`20`]) == `15`
3 | ```
--------------------------------------------------------------------------------
/website/jp/examples/base64_decode.md:
--------------------------------------------------------------------------------
1 | ```
2 | base64_decode('Zm9vCg==') == 'foo'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/base64_encode.md:
--------------------------------------------------------------------------------
1 | ```
2 | base64_encode('foo') == 'Zm9vCg=='
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/ceil.md:
--------------------------------------------------------------------------------
1 | ```
2 | ceil(`1.9`) == `2`
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/compare.md:
--------------------------------------------------------------------------------
1 | ```
2 | compare('a', 'a') == `0`
3 | ```
4 |
5 | ```
6 | compare('a', 'b') == `-1`
7 | ```
8 |
9 | ```
10 | compare('b', 'a') == `1`
11 | ```
12 |
--------------------------------------------------------------------------------
/website/jp/examples/concat.md:
--------------------------------------------------------------------------------
1 | ```
2 | concat('foo', 'bar') == 'foobar'
3 | ```
--------------------------------------------------------------------------------
/website/jp/examples/contains.md:
--------------------------------------------------------------------------------
1 | ### With strings
2 |
3 | ```
4 | contains('foobar', 'bar') == `true`
5 | ```
6 |
7 | ```
8 | contains('foobar', 'not') == `false`
9 | ```
10 |
11 | ### With arrays
12 |
13 | ```
14 | contains(['foo', 'bar'], 'bar') == `true`
15 | ```
16 |
17 | ```
18 | contains(['foo', 'bar'], 'not') == `true`
19 | ```
20 |
--------------------------------------------------------------------------------
/website/jp/examples/divide.md:
--------------------------------------------------------------------------------
1 | ### With numbers
2 |
3 | ```
4 | divide(`1`, `2`) == `0.5`
5 | ```
6 |
7 | ### With durations
8 |
9 | ```
10 | divide('1h', '2h') == `0.5`
11 | ```
12 |
13 | ### With quantities
14 |
15 | ```
16 | divide('1Mi', '2Mi') == `0.5`
17 | ```
18 |
--------------------------------------------------------------------------------
/website/jp/examples/ends_with.md:
--------------------------------------------------------------------------------
1 | ```
2 | ends_with('foobar', 'bar') == `true`
3 | ```
4 |
5 | ```
6 | ends_with('foobar', 'foo') == `false`
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/env.md:
--------------------------------------------------------------------------------
1 | ```
2 | env('MY_ENV_VAR') == 'foo'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/equal_fold.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/find_first.md:
--------------------------------------------------------------------------------
1 | ```
2 | find_first('subject string', 'string', `0`) == `8`
3 | ```
4 |
5 | ```
6 | find_first('subject string', 'string', `8`) == `8`
7 | ```
8 |
9 | ```
10 | find_first('subject string', 'string', `9`) == null
11 | ```
12 |
13 | ```
14 | find_first('subject string', 'string', `0`, `14`) == `8`
15 | ```
16 |
17 | ```
18 | find_first('subject string', 'string', `0`, `13`) == null
19 | ```
20 |
--------------------------------------------------------------------------------
/website/jp/examples/find_last.md:
--------------------------------------------------------------------------------
1 | ```
2 | find_last('subject string', 'string', `0`) == `8`
3 | ```
4 |
5 | ```
6 | find_last('subject string', 'string', `8`) == `8`
7 | ```
8 |
9 | ```
10 | find_last('subject string', 'string', `9`) == null
11 | ```
12 |
13 | ```
14 | find_last('subject string', 'string', `0`, `14`) == `8`
15 | ```
16 |
17 | ```
18 | find_last('subject string', 'string', `0`, `13`) == null
19 | ```
20 |
--------------------------------------------------------------------------------
/website/jp/examples/floor.md:
--------------------------------------------------------------------------------
1 | ```
2 | floor(`1.9`) == `1`
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/from_items.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/group_by.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/items.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/join.md:
--------------------------------------------------------------------------------
1 | ```
2 | join('/', ['a', 'b', 'c']) == 'a/b/c'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/json_parse.md:
--------------------------------------------------------------------------------
1 | ```
2 | json_parse('{"foo":"bar"}') == { foo: 'bar' }
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/keys.md:
--------------------------------------------------------------------------------
1 | ```
2 | keys({bar:'bam',foo:'baz'}) == ['bar','foo']
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/label_match.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/length.md:
--------------------------------------------------------------------------------
1 | ```
2 | length([`10`,`15`,`20`]) == `3`
3 | ```
4 |
5 | ```
6 | length([]) == `0`
7 | ```
8 |
9 | ```
10 | length(null) -> error
11 | ```
12 |
--------------------------------------------------------------------------------
/website/jp/examples/lookup.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/lower.md:
--------------------------------------------------------------------------------
1 | ```
2 | lower('FOOBAR') == 'foobar'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/map.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/max.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/max_by.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/merge.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/min.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/min_by.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/modulo.md:
--------------------------------------------------------------------------------
1 | ```
2 | modulo(`10`, `3`) == `1`
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/multiply.md:
--------------------------------------------------------------------------------
1 | ### With numbers
2 |
3 | ```
4 | multiply(`1`, `2`) == `2`
5 | ```
6 |
7 | ### With durations
8 |
9 | ```
10 | multiply('1h', `2`) == '2h'
11 | ```
12 |
13 | ### With quantities
14 |
15 | ```
16 | multiply('1Mi', `2`) == '2Mi'
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/website/jp/examples/not_null.md:
--------------------------------------------------------------------------------
1 | ```
2 | not_null(null, null, 'foo') == 'foo'
3 | ```
4 |
5 | ```
6 | not_null(null, null) == null
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/object_from_lists.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/pad_left.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/pad_right.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/parse_json.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/parse_yaml.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/path_canonicalize.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/pattern_match.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/random.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/regex_match.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/regex_replace_all.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/regex_replace_all_literal.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/replace.md:
--------------------------------------------------------------------------------
1 | ```
2 | replace('foobar', 'oo', 'ii') == 'fiibar'
3 | ```
4 |
5 | ```
6 | replace('foobar', 'o', 'i', `1`) == 'fiobar'
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/replace_all.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/reverse.md:
--------------------------------------------------------------------------------
1 | ```
2 | reverse('abcd') == 'dcba'
3 | ```
4 |
5 | ```
6 | reverse([`1`, `2`, `3`, `4`]) == [`4`, `3`, `2`, `1`]
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/round.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/semver_compare.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/sort.md:
--------------------------------------------------------------------------------
1 | ```
2 | sort(['b', 'a', 'c']) == ['a', 'b', 'c']
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/sort_by.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/split.md:
--------------------------------------------------------------------------------
1 | ```
2 | split('average|-|min|-|max|-|mean|-|median', '|-|', `3`) == ['average', 'min', 'max', 'mean|-|median']
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/starts_with.md:
--------------------------------------------------------------------------------
1 | ```
2 | starts_with('foobar', 'foo') == `true`
3 | ```
4 |
5 | ```
6 | starts_with('foobar', 'bar') == `false`
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/subtract.md:
--------------------------------------------------------------------------------
1 | ### With numbers
2 |
3 | ```
4 | subtract(`2`, `1`) == `1`
5 | ```
6 |
7 | ### With durations
8 |
9 | ```
10 | subtract('2h', '1h') == '1h'
11 | ```
12 |
13 | ### With quantities
14 |
15 | ```
16 | subtract('2Mi', '1Mi') == '1Mi'
17 | ```
18 |
--------------------------------------------------------------------------------
/website/jp/examples/sum.md:
--------------------------------------------------------------------------------
1 | ```
2 | sum(`[]`) == `0`
3 | ```
4 |
5 | ```
6 | sum([`10`, `15`]) == `25`
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/time_add.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_after.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_before.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_between.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_diff.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_now.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_now_utc.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_parse.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_since.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_to_cron.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_truncate.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/time_utc.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/to_array.md:
--------------------------------------------------------------------------------
1 | ```
2 | to_array(`true`) == [`true`]
3 | ```
4 |
5 | ```
6 | to_array([`10`, `15`, `20`]) == [`10`, `15`, `20`]
7 | ```
8 |
9 | ```
10 | to_array(`[]`) == []
11 | ```
12 |
--------------------------------------------------------------------------------
/website/jp/examples/to_boolean.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/to_lower.md:
--------------------------------------------------------------------------------
1 | ```
2 | lower('FOOBAR') == 'foobar'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/to_number.md:
--------------------------------------------------------------------------------
1 | ```
2 | to_number('1.0') == `1`
3 | ```
4 |
5 | ```
6 | to_number(`1.0`) == `1`
7 | ```
8 |
9 | ```
10 | to_number(`false`) == null
11 | ```
12 |
--------------------------------------------------------------------------------
/website/jp/examples/to_string.md:
--------------------------------------------------------------------------------
1 | ```
2 | to_string(`2`) == '2'
3 | ```
4 |
5 | ```
6 | to_string('foobar') == 'foobar'
7 | ```
8 |
9 | ```
10 | to_string(null) == 'null'
11 | ```
12 |
13 | ```
14 | to_string({bar:'bam',foo:'baz'}) == '{"bar":"bam","foo":"baz"}'
15 | ```
16 |
--------------------------------------------------------------------------------
/website/jp/examples/to_upper.md:
--------------------------------------------------------------------------------
1 | ```
2 | upper('foobar') == 'FOOBAR'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/trim.md:
--------------------------------------------------------------------------------
1 | ```
2 | trim(' foobar ', 'fbr ') == 'ooba'
3 | ```
4 |
5 | ```
6 | trim(' foobar ', 'fbr') == ' foobar '
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/trim_left.md:
--------------------------------------------------------------------------------
1 | ```
2 | trim_left(' foobar ', 'fbr ') == 'oobar '
3 | ```
4 |
5 | ```
6 | trim_left(' foobar ', 'fbr') == ' foobar '
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/trim_prefix.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/trim_right.md:
--------------------------------------------------------------------------------
1 | ```
2 | trim_right(' foobar ', 'fbr ') == ' fooba'
3 | ```
4 |
5 | ```
6 | trim_right(' foobar ', 'fbr') == ' foobar '
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/trim_space.md:
--------------------------------------------------------------------------------
1 | ```
2 | trim_space(' foobar ') == 'foobar'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/truncate.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/type.md:
--------------------------------------------------------------------------------
1 | ```
2 | type(`false`) == 'boolean'
3 | ```
4 |
5 | ```
6 | type(null) == 'null'
7 | ```
8 |
9 | ```
10 | type('foobar') == 'string'
11 | ```
12 |
--------------------------------------------------------------------------------
/website/jp/examples/upper.md:
--------------------------------------------------------------------------------
1 | ```
2 | upper('foobar') == 'FOOBAR'
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/values.md:
--------------------------------------------------------------------------------
1 | ```
2 | values({bar:'bam',foo:'baz'}) == ['bam','baz']
3 | ```
4 |
--------------------------------------------------------------------------------
/website/jp/examples/wildcard.md:
--------------------------------------------------------------------------------
1 | ```
2 | wildcard('foo*', 'foobar') == `true`
3 | ```
4 |
5 | ```
6 | wildcard('fooba?', 'foobar') == `true`
7 | ```
8 |
--------------------------------------------------------------------------------
/website/jp/examples/x509_decode.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/x_k8s_exists.md:
--------------------------------------------------------------------------------
1 | !!! info "Clustered resources"
2 |
3 | For clustered resources, you can leave the namespace empty `''`.
4 |
5 | ```
6 | # `$client` is a binding pointing to a Kubernetes client
7 |
8 | x_k8s_exists($client, 'apps/v1', 'Deployment', 'crossplane-system', 'crossplane')
9 | ```
10 |
--------------------------------------------------------------------------------
/website/jp/examples/x_k8s_get.md:
--------------------------------------------------------------------------------
1 | !!! info "Clustered resources"
2 |
3 | For clustered resources, you can leave the namespace empty `''`.
4 |
5 | ```
6 | # `$client` is a binding pointing to a Kubernetes client
7 |
8 | x_k8s_get($client, 'apps/v1', 'Deployment', 'crossplane-system', 'crossplane')
9 | ```
10 |
--------------------------------------------------------------------------------
/website/jp/examples/x_k8s_list.md:
--------------------------------------------------------------------------------
1 | !!! info "Clustered resources"
2 |
3 | For clustered resources, you can leave the namespace empty `''`.
4 |
5 | ```
6 | # `$client` is a binding pointing to a Kubernetes client
7 |
8 | x_k8s_list($client, 'apps/v1', 'Deployment', 'crossplane-system')
9 | ```
10 |
--------------------------------------------------------------------------------
/website/jp/examples/x_k8s_resource_exists.md:
--------------------------------------------------------------------------------
1 | !!! info "Clustered resources"
2 |
3 | For clustered resources, you can leave the namespace empty `''`.
4 |
5 | ```
6 | # `$client` is a binding pointing to a Kubernetes client
7 |
8 | x_k8s_resource_exists($client, 'apps/v1', 'Deployment')
9 | ```
10 |
--------------------------------------------------------------------------------
/website/jp/examples/x_k8s_server_version.md:
--------------------------------------------------------------------------------
1 | ```
2 | # `$client` is a binding pointing to a Kubernetes client
3 |
4 | x_k8s_server_version($client)
5 | ```
6 |
--------------------------------------------------------------------------------
/website/jp/examples/x_metrics_decode.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/website/jp/examples/zip.md:
--------------------------------------------------------------------------------
1 | ```
2 | zip(['a', 'b'], [`1`, `2`]) == [['a', `1`], ['b', `2`]]
3 | ```
4 |
--------------------------------------------------------------------------------