mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-15 17:51:20 +00:00
feat: add cli command (#7778)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
6d9d3b7f4c
commit
4a7f7ff30b
5 changed files with 163 additions and 1 deletions
18
cmd/cli/kubectl-kyverno/create/command.go
Normal file
18
cmd/cli/kubectl-kyverno/create/command.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package create
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/create/test"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Command() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "create",
|
||||||
|
Example: "",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return cmd.Help()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.AddCommand(test.Command())
|
||||||
|
return cmd
|
||||||
|
}
|
8
cmd/cli/kubectl-kyverno/create/templates/templates.go
Normal file
8
cmd/cli/kubectl-kyverno/create/templates/templates.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed test.yaml
|
||||||
|
var TestTemplate string
|
28
cmd/cli/kubectl-kyverno/create/templates/test.yaml
Normal file
28
cmd/cli/kubectl-kyverno/create/templates/test.yaml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# test name
|
||||||
|
name: {{ .Name }}
|
||||||
|
|
||||||
|
# list of policy files
|
||||||
|
policies:
|
||||||
|
{{- range .Policies }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# list of resource files
|
||||||
|
resources:
|
||||||
|
{{- range .Resources }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# variables file (optional)
|
||||||
|
variables: {{ .Values }}
|
||||||
|
|
||||||
|
# list of expected results
|
||||||
|
results:
|
||||||
|
{{- range .Results }}
|
||||||
|
- policy: {{ .Policy }}
|
||||||
|
rule: {{ .Rule }}
|
||||||
|
resource: {{ .Resource }}
|
||||||
|
namespace: {{ .Namespace }}
|
||||||
|
kind: {{ .Kind }}
|
||||||
|
result: {{ .Result }}
|
||||||
|
{{- end }}
|
107
cmd/cli/kubectl-kyverno/create/test/command.go
Normal file
107
cmd/cli/kubectl-kyverno/create/test/command.go
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/create/templates"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type result struct {
|
||||||
|
Policy string
|
||||||
|
Rule string
|
||||||
|
Resource string
|
||||||
|
Namespace string
|
||||||
|
Kind string
|
||||||
|
PatchedResource string
|
||||||
|
Result string
|
||||||
|
}
|
||||||
|
|
||||||
|
type options struct {
|
||||||
|
Name string
|
||||||
|
Policies []string
|
||||||
|
Resources []string
|
||||||
|
Values string
|
||||||
|
Results []*result
|
||||||
|
}
|
||||||
|
|
||||||
|
func Command() *cobra.Command {
|
||||||
|
var path string
|
||||||
|
var options options
|
||||||
|
var pass, fail, skip []string
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "test",
|
||||||
|
Short: "Create a Kyverno test file.",
|
||||||
|
Example: "kyverno create test -p policy.yaml -r resource.yaml -f values.yaml --pass policy-name,rule-name,resource-name,resource-namespace,resource-kind",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
tmpl, err := template.New("test").Parse(templates.TestTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, result := range pass {
|
||||||
|
result := parseResult(result, "pass")
|
||||||
|
if result != nil {
|
||||||
|
options.Results = append(options.Results, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, result := range fail {
|
||||||
|
result := parseResult(result, "fail")
|
||||||
|
if result != nil {
|
||||||
|
options.Results = append(options.Results, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, result := range skip {
|
||||||
|
result := parseResult(result, "skip")
|
||||||
|
if result != nil {
|
||||||
|
options.Results = append(options.Results, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output := os.Stdout
|
||||||
|
if path != "" {
|
||||||
|
file, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
output = file
|
||||||
|
}
|
||||||
|
return tmpl.Execute(output, options)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().StringVarP(&path, "output", "o", "", "Output path (uses standard console output if not set)")
|
||||||
|
cmd.Flags().StringVarP(&options.Name, "name", "n", "test-name", "Test name")
|
||||||
|
cmd.Flags().StringSliceVarP(&options.Policies, "policy", "p", nil, "List of policy files")
|
||||||
|
cmd.Flags().StringSliceVarP(&options.Resources, "resource", "r", nil, "List of resource files")
|
||||||
|
cmd.Flags().StringVarP(&options.Values, "values", "f", "", "Values file")
|
||||||
|
cmd.Flags().StringArrayVar(&pass, "pass", nil, "Expected `pass` results")
|
||||||
|
cmd.Flags().StringArrayVar(&fail, "fail", nil, "Expected `fail` results")
|
||||||
|
cmd.Flags().StringArrayVar(&skip, "skip", nil, "Expected `skip` results")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseResult(test string, status string) *result {
|
||||||
|
parts := strings.Split(test, ",")
|
||||||
|
if len(parts) == 5 {
|
||||||
|
return &result{
|
||||||
|
Policy: parts[0],
|
||||||
|
Rule: parts[1],
|
||||||
|
Resource: parts[2],
|
||||||
|
Namespace: parts[3],
|
||||||
|
Kind: parts[4],
|
||||||
|
Result: status,
|
||||||
|
}
|
||||||
|
} else if len(parts) == 6 {
|
||||||
|
return &result{
|
||||||
|
Policy: parts[0],
|
||||||
|
Rule: parts[1],
|
||||||
|
Resource: parts[2],
|
||||||
|
Namespace: parts[3],
|
||||||
|
Kind: parts[4],
|
||||||
|
PatchedResource: parts[5],
|
||||||
|
Result: status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apply"
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apply"
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/create"
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/jp"
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/jp"
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/oci"
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/oci"
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test"
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test"
|
||||||
|
@ -48,7 +49,7 @@ func enableExperimental() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerCommands(cli *cobra.Command) {
|
func registerCommands(cli *cobra.Command) {
|
||||||
cli.AddCommand(version.Command(), apply.Command(), test.Command(), jp.Command())
|
cli.AddCommand(version.Command(), create.Command(), apply.Command(), test.Command(), jp.Command())
|
||||||
if enableExperimental() {
|
if enableExperimental() {
|
||||||
cli.AddCommand(oci.Command())
|
cli.AddCommand(oci.Command())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue