Skip to content

Commit

Permalink
Update Kyverno test command (#1608)
Browse files Browse the repository at this point in the history
* fix link (#1566)

Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* update icon in chart.yaml

Signed-off-by: Shuting Zhao <shutting06@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* Adding default policies for restricted mode and adding notes to helm install (#1556)

* Adding default policies for restricted mode, taking validationFailureAction from values.yaml and adding notes on helm install

Signed-off-by: Raj Das <mail.rajdas@gmail.com>

* Adding emoji

Signed-off-by: Raj Das <mail.rajdas@gmail.com>

* Update NOTES.txt

* minor fix

Signed-off-by: Raj Das <mail.rajdas@gmail.com>

* adding to readme

Signed-off-by: Raj Das <mail.rajdas@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* update links and formatting in PR template (#1573)

* update links and formatting in PR template

Signed-off-by: Chip Zoller <chipzoller@gmail.com>

* update policy submission request template

Signed-off-by: Chip Zoller <chipzoller@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* fix: restricting empty value to pass through the validation checks (#1574)

Signed-off-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* Actually fix contributor link in PR template (#1575)

* update links and formatting in PR template

Signed-off-by: Chip Zoller <chipzoller@gmail.com>

* update policy submission request template

Signed-off-by: Chip Zoller <chipzoller@gmail.com>

* actually fix contrib guidelines

Signed-off-by: Chip Zoller <chipzoller@gmail.com>

* actually fix contrib guidelines

Signed-off-by: Chip Zoller <chipzoller@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* code improvement (#1567)

* code improvement

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* added if conditions

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* fixed unit test cases

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* feat(operators): support subset checking for in and notin (#1555)

* feat(operators): support subset checking for in and notin

Signed-off-by: Arsh Sharma <arshsharma461@gmail.com>

* feat(operators): fixed NotIn function

Signed-off-by: Arsh Sharma <arshsharma461@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* panic fix (#1601)

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>
Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* update kyverno cli test cmd

Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* code indentation

Signed-off-by: vyankatesh <vyankatesh@neualto.com>

* change  help text

Signed-off-by: vyankatesh <vyankatesh@neualto.com>

Co-authored-by: Dekel <dekelb@users.noreply.github.com>
Co-authored-by: Shuting Zhao <shutting06@gmail.com>
Co-authored-by: Raj Babu Das <mail.rajdas@gmail.com>
Co-authored-by: Chip Zoller <chipzoller@gmail.com>
Co-authored-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com>
Co-authored-by: Pooja Singh <36136335+NoSkillGirl@users.noreply.github.com>
Co-authored-by: Arsh Sharma <56963264+RinkiyaKeDad@users.noreply.github.com>
Co-authored-by: vyankatesh <vyankatesh@neualto.com>
  • Loading branch information
9 people committed Feb 17, 2021
1 parent 731474a commit 164885d
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 53 deletions.
6 changes: 3 additions & 3 deletions pkg/kyverno/apply/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func applyCommandHelper(resourcePaths []string, cluster bool, policyReport bool,
return validateEngineResponses, rc, resources, skippedPolicies, sanitizederror.NewWithError("pass the values either using set flag or values_file flag", err)
}

variables, valuesMap, err := common.GetVariable(variablesString, valuesFile)
variables, valuesMap, err := common.GetVariable(variablesString, valuesFile, fs, false, "")
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return validateEngineResponses, rc, resources, skippedPolicies, sanitizederror.NewWithError("failed to decode yaml", err)
Expand Down Expand Up @@ -180,7 +180,7 @@ func applyCommandHelper(resourcePaths []string, cluster bool, policyReport bool,
return validateEngineResponses, rc, resources, skippedPolicies, sanitizederror.NewWithError("a stdin pipe can be used for either policies or resources, not both", err)
}

policies, err := common.GetPoliciesFromPaths(fs, policyPaths, false)
policies, err := common.GetPoliciesFromPaths(fs, policyPaths, false, "")
if err != nil {
fmt.Printf("Error: failed to load policies\nCause: %s\n", err)
os.Exit(1)
Expand All @@ -205,7 +205,7 @@ func applyCommandHelper(resourcePaths []string, cluster bool, policyReport bool,
}
}

resources, err = common.GetResourceAccordingToResourcePath(fs, resourcePaths, cluster, mutatedPolicies, dClient, namespace, policyReport, false)
resources, err = common.GetResourceAccordingToResourcePath(fs, resourcePaths, cluster, mutatedPolicies, dClient, namespace, policyReport, false, "")
if err != nil {
fmt.Printf("Error: failed to load resources\nCause: %s\n", err)
os.Exit(1)
Expand Down
28 changes: 22 additions & 6 deletions pkg/kyverno/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,11 @@ func RemoveDuplicateVariables(matches [][]string) string {
}

// GetVariable - get the variables from console/file
func GetVariable(variablesString, valuesFile string) (map[string]string, map[string]map[string]Resource, error) {
func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit bool, policyresoucePath string) (map[string]string, map[string]map[string]Resource, error) {
valuesMap := make(map[string]map[string]Resource)
variables := make(map[string]string)
var yamlFile []byte
var err error
if variablesString != "" {
kvpairs := strings.Split(strings.Trim(variablesString, " "), ",")
for _, kvpair := range kvpairs {
Expand All @@ -311,7 +313,16 @@ func GetVariable(variablesString, valuesFile string) (map[string]string, map[str
}
}
if valuesFile != "" {
yamlFile, err := ioutil.ReadFile(valuesFile)
if isGit {
filep, err := fs.Open(filepath.Join(policyresoucePath, valuesFile))
if err != nil {
fmt.Printf("Unable to open variable file: %s. error: %s", valuesFile, err)
}
yamlFile, err = ioutil.ReadAll(filep)
} else {
yamlFile, err = ioutil.ReadFile(valuesFile)
}

if err != nil {
return variables, valuesMap, sanitizederror.NewWithError("unable to read yaml", err)
}
Expand Down Expand Up @@ -500,14 +511,19 @@ func PrintMutatedOutput(mutateLogPath string, mutateLogPathIsDir bool, yaml stri
}

// GetPoliciesFromPaths - get policies according to the resource path
func GetPoliciesFromPaths(fs billy.Filesystem, dirPath []string, isGit bool) (policies []*v1.ClusterPolicy, err error) {
func GetPoliciesFromPaths(fs billy.Filesystem, dirPath []string, isGit bool, policyresoucePath string) (policies []*v1.ClusterPolicy, err error) {
var errors []error
if isGit {
for _, pp := range dirPath {
filep, err := fs.Open(pp)
filep, err := fs.Open(filepath.Join(policyresoucePath, pp))
if err != nil {
fmt.Printf("Error: file not available with path %s: %v", filep.Name(), err.Error())
continue
}
bytes, err := ioutil.ReadAll(filep)
if err != nil {
fmt.Printf("Error: failed to read file %s: %v", filep.Name(), err.Error())
continue
}
policyBytes, err := yaml.ToJSON(bytes)
if err != nil {
Expand Down Expand Up @@ -558,9 +574,9 @@ func GetPoliciesFromPaths(fs billy.Filesystem, dirPath []string, isGit bool) (po

// GetResourceAccordingToResourcePath - get resources according to the resource path
func GetResourceAccordingToResourcePath(fs billy.Filesystem, resourcePaths []string,
cluster bool, policies []*v1.ClusterPolicy, dClient *client.Client, namespace string, policyReport bool, isGit bool) (resources []*unstructured.Unstructured, err error) {
cluster bool, policies []*v1.ClusterPolicy, dClient *client.Client, namespace string, policyReport bool, isGit bool, policyresoucePath string) (resources []*unstructured.Unstructured, err error) {
if isGit {
resources, err = GetResourcesWithTest(fs, policies, resourcePaths, isGit)
resources, err = GetResourcesWithTest(fs, policies, resourcePaths, isGit, policyresoucePath)
if err != nil {
return nil, sanitizederror.NewWithError("failed to extract the resources", err)
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/kyverno/common/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"path/filepath"
"strings"

"github.com/go-git/go-billy/v5"
Expand Down Expand Up @@ -100,7 +101,7 @@ func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient
}

// GetResourcesWithTest with gets matched resources by the given policies
func GetResourcesWithTest(fs billy.Filesystem, policies []*v1.ClusterPolicy, resourcePaths []string, isGit bool) ([]*unstructured.Unstructured, error) {
func GetResourcesWithTest(fs billy.Filesystem, policies []*v1.ClusterPolicy, resourcePaths []string, isGit bool, policyresoucePath string) ([]*unstructured.Unstructured, error) {
resources := make([]*unstructured.Unstructured, 0)
var resourceTypesMap = make(map[string]bool)
var resourceTypes []string
Expand All @@ -119,7 +120,7 @@ func GetResourcesWithTest(fs billy.Filesystem, policies []*v1.ClusterPolicy, res
var resourceBytes []byte
var err error
if isGit {
filep, err := fs.Open(resourcePath)
filep, err := fs.Open(filepath.Join(policyresoucePath, resourcePath))
if err != nil {
fmt.Printf("Unable to open resource file: %s. error: %s", resourcePath, err)
continue
Expand Down
119 changes: 79 additions & 40 deletions pkg/kyverno/test/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ import (

// Command returns version command
func Command() *cobra.Command {

var valuesFile string
return &cobra.Command{
var cmd *cobra.Command
var valuesFile, fileName string
cmd = &cobra.Command{
Use: "test",
Short: "Shows current test of kyverno",
Short: "run tests from directory",
RunE: func(cmd *cobra.Command, dirPath []string) (err error) {
defer func() {
if err != nil {
Expand All @@ -48,14 +48,16 @@ func Command() *cobra.Command {
}
}
}()
err = testCommandExecute(dirPath, valuesFile)
err = testCommandExecute(dirPath, valuesFile, fileName)
if err != nil {
log.Log.V(3).Info("a directory is required")
return err
}
return nil
},
}
cmd.Flags().StringVarP(&fileName, "file-name", "f", "test.yaml", "test filename")
return cmd
}

type Test struct {
Expand Down Expand Up @@ -103,7 +105,7 @@ type Values struct {
Policies []Policy `json:"policies"`
}

func testCommandExecute(dirPath []string, valuesFile string) (err error) {
func testCommandExecute(dirPath []string, valuesFile string, fileName string) (err error) {
var errors []error
fs := memfs.New()

Expand Down Expand Up @@ -134,45 +136,35 @@ func testCommandExecute(dirPath []string, valuesFile string) (err error) {
sort.Strings(policyYamls)
for _, yamlFilePath := range policyYamls {
file, err := fs.Open(yamlFilePath)
bytes, err := ioutil.ReadAll(file)
if err != nil {
sanitizederror.NewWithError("Error: failed to read file", err)
if strings.Contains(file.Name(), fileName) {
policyresoucePath := strings.Trim(yamlFilePath, fileName)
bytes, err := ioutil.ReadAll(file)
if err != nil {
sanitizederror.NewWithError("Error: failed to read file", err)
continue
}
policyBytes, err := yaml.ToJSON(bytes)
if err != nil {
sanitizederror.NewWithError("failed to convert to JSON", err)
continue
}
if err := applyPoliciesFromPath(fs, policyBytes, valuesFile, true, policyresoucePath); err != nil {
return sanitizederror.NewWithError("failed to apply test command", err)
}
}
policyBytes, err := yaml.ToJSON(bytes)
if err != nil {
sanitizederror.NewWithError("failed to convert to JSON", err)
sanitizederror.NewWithError("Error: failed to open file", err)
continue
}
if err := applyPoliciesFromPath(fs, policyBytes, valuesFile, true); err != nil {
return sanitizederror.NewWithError("failed to apply test command", err)
}
}
} else {
path := filepath.Clean(dirPath[0])
fileDesc, err := os.Stat(path)
if err != nil {
errors = append(errors, err)
}
if fileDesc.IsDir() {
files, err := ioutil.ReadDir(path)
if err != nil {
errors = append(errors, fmt.Errorf("failed to read %v: %v", path, err.Error()))
}
for _, file := range files {
fmt.Printf("\napplying test on file %s...", file.Name())

yamlFile, err := ioutil.ReadFile(filepath.Join(path, file.Name()))
if err != nil {
return sanitizederror.NewWithError("unable to read yaml", err)
}
valuesBytes, err := yaml.ToJSON(yamlFile)
if err != nil {
return sanitizederror.NewWithError("failed to convert json", err)
}
if err := applyPoliciesFromPath(fs, valuesBytes, valuesFile, false); err != nil {
return sanitizederror.NewWithError("failed to apply test command", err)
}
}
err := getLocalDirTestFiles(fs, path, fileName, valuesFile)
if err != nil {
errors = append(errors, err)
}
if len(errors) > 0 && log.Log.V(1).Enabled() {
fmt.Printf("ignoring errors: \n")
Expand All @@ -184,6 +176,36 @@ func testCommandExecute(dirPath []string, valuesFile string) (err error) {
return nil
}

func getLocalDirTestFiles(fs billy.Filesystem, path, fileName, valuesFile string) error {
files, err := ioutil.ReadDir(path)
if err != nil {
return fmt.Errorf("failed to read %v: %v", path, err.Error())
}
for _, file := range files {
if file.IsDir() {
getLocalDirTestFiles(fs, filepath.Join(path, file.Name()), fileName, valuesFile)
continue
}
if strings.Contains(file.Name(), fileName) {
yamlFile, err := ioutil.ReadFile(filepath.Join(path, file.Name()))
if err != nil {
sanitizederror.NewWithError("unable to read yaml", err)
continue
}
valuesBytes, err := yaml.ToJSON(yamlFile)
if err != nil {
sanitizederror.NewWithError("failed to convert json", err)
continue
}
if err := applyPoliciesFromPath(fs, valuesBytes, valuesFile, false, path); err != nil {
sanitizederror.NewWithError("failed to apply test command", err)
continue
}
}
}
return nil
}

func buildPolicyResults(resps []*response.EngineResponse) map[string][]interface{} {
results := make(map[string][]interface{})
infos := policyreport.GeneratePRsFromEngineResponse(resps, log.Log)
Expand All @@ -210,7 +232,18 @@ func buildPolicyResults(resps []*response.EngineResponse) map[string][]interface
return results
}

func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile string, isGit bool) (err error) {
func getPolicyResouceFullPath(path []string, policyresoucePath string, isGit bool) []string {
var pol []string
if !isGit {
for _, p := range path {
pol = append(pol, filepath.Join(policyresoucePath, p))
}
return pol
}
return path
}

func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile string, isGit bool, policyresoucePath string) (err error) {
openAPIController, err := openapi.NewOpenAPIController()
engineResponses := make([]*response.EngineResponse, 0)
validateEngineResponses := make([]*response.EngineResponse, 0)
Expand All @@ -222,14 +255,21 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile s
if err := json.Unmarshal(policyBytes, values); err != nil {
return sanitizederror.NewWithError("failed to decode yaml", err)
}
_, valuesMap, err := common.GetVariable(variablesString, values.Variables)

fmt.Printf("\nExecuting %s...", values.Name)

_, valuesMap, err := common.GetVariable(variablesString, values.Variables, fs, isGit, policyresoucePath)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return sanitizederror.NewWithError("failed to decode yaml", err)
}
return err
}
policies, err := common.GetPoliciesFromPaths(fs, values.Policies, isGit)

fullPolicyPath := getPolicyResouceFullPath(values.Policies, policyresoucePath, isGit)
fullResourcePath := getPolicyResouceFullPath(values.Resources, policyresoucePath, isGit)

policies, err := common.GetPoliciesFromPaths(fs, fullPolicyPath, isGit, policyresoucePath)
if err != nil {
fmt.Printf("Error: failed to load policies\nCause: %s\n", err)
os.Exit(1)
Expand All @@ -240,7 +280,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile s
return sanitizederror.NewWithError("failed to mutate policy", err)
}
}
resources, err := common.GetResourceAccordingToResourcePath(fs, values.Resources, false, mutatedPolicies, dClient, "", false, isGit)
resources, err := common.GetResourceAccordingToResourcePath(fs, fullResourcePath, false, mutatedPolicies, dClient, "", false, isGit, policyresoucePath)
if err != nil {
fmt.Printf("Error: failed to load resources\nCause: %s\n", err)
os.Exit(1)
Expand All @@ -259,7 +299,6 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile s
for _, policy := range mutatedPolicies {
err := policy2.Validate(policy, nil, true, openAPIController)
if err != nil {
fmt.Println("valuesMap1")
log.Log.V(3).Info(fmt.Sprintf("skipping policy %v as it is not valid", policy.Name), "error", err)
continue
}
Expand Down
11 changes: 9 additions & 2 deletions pkg/kyverno/test/git.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package test

import (
"os"
"path/filepath"

"github.com/go-git/go-billy/v5"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/storage/memory"
"os"
"path/filepath"
)

func clone(path string, fs billy.Filesystem) (*git.Repository, error) {
Expand All @@ -25,6 +26,12 @@ func listYAMLs(fs billy.Filesystem, path string) ([]string, error) {
for _, fi := range fis {
name := filepath.Join(path, fi.Name())
if fi.IsDir() {
moreYAMLs, err := listYAMLs(fs, name)
if err != nil {
return nil, err
}

yamls = append(yamls, moreYAMLs...)
continue
}

Expand Down

0 comments on commit 164885d

Please sign in to comment.