Skip to content

Commit

Permalink
ignore non-policy files while loading
Browse files Browse the repository at this point in the history
  • Loading branch information
JimBugwadia committed Dec 6, 2020
1 parent c80ac55 commit c766512
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 102 deletions.
95 changes: 47 additions & 48 deletions pkg/kyverno/apply/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/kyverno/common"
sanitizedError "github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
"github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
"github.com/kyverno/kyverno/pkg/openapi"
policy2 "github.com/kyverno/kyverno/pkg/policy"
"github.com/kyverno/kyverno/pkg/utils"
Expand Down Expand Up @@ -59,18 +59,7 @@ type SkippedPolicy struct {
Variable string `json:"variable"`
}

func Command() *cobra.Command {
var cmd *cobra.Command
var resourcePaths []string
var cluster, policyReport bool
var mutateLogPath, variablesString, valuesFile, namespace string

kubernetesConfig := genericclioptions.NewConfigFlags(true)

cmd = &cobra.Command{
Use: "apply",
Short: "applies policies on resources",
Example: fmt.Sprintf(`
var applyHelp = `
To apply on a resource:
kyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2
Expand Down Expand Up @@ -112,33 +101,46 @@ To apply policy with variables:
<variable1 in policy2>: <value>
<variable2 in policy2>: <value>
More info: https://kyverno.io/docs/kyverno-cli/
`),
More info: https://kyverno.io/docs/kyverno-cli/
`

func Command() *cobra.Command {
var cmd *cobra.Command
var resourcePaths []string
var cluster, policyReport bool
var mutateLogPath, variablesString, valuesFile, namespace string

kubernetesConfig := genericclioptions.NewConfigFlags(true)

cmd = &cobra.Command{
Use: "apply",
Short: "applies policies on resources",
Example: applyHelp,
RunE: func(cmd *cobra.Command, policyPaths []string) (err error) {
defer func() {
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
if !sanitizederror.IsErrorSanitized(err) {
log.Log.Error(err, "failed to sanitize")
err = fmt.Errorf("internal error")
}
}
}()

if valuesFile != "" && variablesString != "" {
return sanitizedError.NewWithError("pass the values either using set flag or values_file flag", err)
return sanitizederror.NewWithError("pass the values either using set flag or values_file flag", err)
}

variables, valuesMap, err := getVariable(variablesString, valuesFile)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to decode yaml", err)
if !sanitizederror.IsErrorSanitized(err) {
return sanitizederror.NewWithError("failed to decode yaml", err)
}
return err
}

openAPIController, err := openapi.NewOpenAPIController()
if err != nil {
return sanitizedError.NewWithError("failed to initialize openAPIController", err)
return sanitizederror.NewWithError("failed to initialize openAPIController", err)
}

var dClient *client.Client
Expand All @@ -154,33 +156,30 @@ To apply policy with variables:
}

if len(policyPaths) == 0 {
return sanitizedError.NewWithError(fmt.Sprintf("require policy"), err)
return sanitizederror.NewWithError(fmt.Sprintf("require policy"), err)
}

policies, err := common.ValidateAndGetPolicies(policyPaths)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to mutate policies.", err)
}
return err
policies, errors := common.GetPolicies(policyPaths)
if len(errors) > 0 && len(policies) == 0 {
return sanitizederror.NewWithErrors("failed to read policies", errors)
}

if len(resourcePaths) == 0 && !cluster {
return sanitizedError.NewWithError(fmt.Sprintf("resource file(s) or cluster required"), err)
return sanitizederror.NewWithError(fmt.Sprintf("resource file(s) or cluster required"), err)
}

mutateLogPathIsDir, err := checkMutateLogPath(mutateLogPath)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to create file/folder", err)
if !sanitizederror.IsErrorSanitized(err) {
return sanitizederror.NewWithError("failed to create file/folder", err)
}
return err
}

mutatedPolicies, err := mutatePolices(policies)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to mutate policy", err)
if !sanitizederror.IsErrorSanitized(err) {
return sanitizederror.NewWithError("failed to mutate policy", err)
}
}

Expand Down Expand Up @@ -244,12 +243,12 @@ To apply policy with variables:
}

if len(common.PolicyHasVariables(*policy)) > 0 && len(thisPolicyResourceValues) == 0 {
return sanitizedError.NewWithError(fmt.Sprintf("policy %s have variables. pass the values for the variables using set/values_file flag", policy.Name), err)
return sanitizederror.NewWithError(fmt.Sprintf("policy %s have variables. pass the values for the variables using set/values_file flag", policy.Name), err)
}

ers, validateErs, err := applyPolicyOnResource(policy, resource, mutateLogPath, mutateLogPathIsDir, thisPolicyResourceValues, rc, policyReport)
if err != nil {
return sanitizedError.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err)
return sanitizederror.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err)
}
engineResponses = append(engineResponses, ers...)
validateEngineResponses = append(validateEngineResponses, validateErs)
Expand Down Expand Up @@ -285,17 +284,17 @@ func getVariable(variablesString, valuesFile string) (variables map[string]strin
if valuesFile != "" {
yamlFile, err := ioutil.ReadFile(valuesFile)
if err != nil {
return variables, valuesMap, sanitizedError.NewWithError("unable to read yaml", err)
return variables, valuesMap, sanitizederror.NewWithError("unable to read yaml", err)
}

valuesBytes, err := yaml.ToJSON(yamlFile)
if err != nil {
return variables, valuesMap, sanitizedError.NewWithError("failed to convert json", err)
return variables, valuesMap, sanitizederror.NewWithError("failed to convert json", err)
}

values := &Values{}
if err := json.Unmarshal(valuesBytes, values); err != nil {
return variables, valuesMap, sanitizedError.NewWithError("failed to decode yaml", err)
return variables, valuesMap, sanitizederror.NewWithError("failed to decode yaml", err)
}

for _, p := range values.Policies {
Expand Down Expand Up @@ -323,8 +322,8 @@ func checkMutateLogPath(mutateLogPath string) (mutateLogPathIsDir bool, err erro

err := createFileOrFolder(mutateLogPath, mutateLogPathIsDir)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return mutateLogPathIsDir, sanitizedError.NewWithError("failed to create file/folder.", err)
if !sanitizederror.IsErrorSanitized(err) {
return mutateLogPathIsDir, sanitizederror.NewWithError("failed to create file/folder.", err)
}
return mutateLogPathIsDir, err
}
Expand All @@ -345,7 +344,7 @@ func getResourceAccordingToResourcePath(resourcePaths []string, cluster bool, po
yamlBytes := []byte(resourceStr)
resources, err = common.GetResource(yamlBytes)
if err != nil {
return resources, sanitizedError.NewWithError("failed to extract the resources", err)
return resources, sanitizederror.NewWithError("failed to extract the resources", err)
}
}
} else if (len(resourcePaths) > 0 && resourcePaths[0] != "-") || len(resourcePaths) < 0 || cluster {
Expand Down Expand Up @@ -434,7 +433,7 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst
} else {
err := printMutatedOutput(mutateLogPath, mutateLogPathIsDir, string(yamlEncodedResource), resource.GetName()+"-mutated")
if err != nil {
return engineResponses, response.EngineResponse{}, sanitizedError.NewWithError("failed to print mutated result", err)
return engineResponses, response.EngineResponse{}, sanitizederror.NewWithError("failed to print mutated result", err)
}
fmt.Printf("\n\nMutation:\nMutation has been applied successfully. Check the files.")
}
Expand Down Expand Up @@ -503,8 +502,8 @@ func mutatePolices(policies []*v1.ClusterPolicy) ([]*v1.ClusterPolicy, error) {
for _, policy := range policies {
p, err := common.MutatePolicy(policy, logger)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return nil, sanitizedError.NewWithError("failed to mutate policy.", err)
if !sanitizederror.IsErrorSanitized(err) {
return nil, sanitizederror.NewWithError("failed to mutate policy.", err)
}
return nil, err
}
Expand Down Expand Up @@ -557,30 +556,30 @@ func createFileOrFolder(mutateLogPath string, mutateLogPathIsDir bool) error {
if os.IsNotExist(err) {
errDir := os.MkdirAll(folderPath, 0755)
if errDir != nil {
return sanitizedError.NewWithError(fmt.Sprintf("failed to create directory"), err)
return sanitizederror.NewWithError(fmt.Sprintf("failed to create directory"), err)
}
}
}

file, err := os.OpenFile(mutateLogPath, os.O_RDONLY|os.O_CREATE, 0644)
if err != nil {
return sanitizedError.NewWithError(fmt.Sprintf("failed to create file"), err)
return sanitizederror.NewWithError(fmt.Sprintf("failed to create file"), err)
}

err = file.Close()
if err != nil {
return sanitizedError.NewWithError(fmt.Sprintf("failed to close file"), err)
return sanitizederror.NewWithError(fmt.Sprintf("failed to close file"), err)
}

} else {
errDir := os.MkdirAll(mutateLogPath, 0755)
if errDir != nil {
return sanitizedError.NewWithError(fmt.Sprintf("failed to create directory"), err)
return sanitizederror.NewWithError(fmt.Sprintf("failed to create directory"), err)
}
}

} else {
return sanitizedError.NewWithError(fmt.Sprintf("failed to describe file"), err)
return sanitizederror.NewWithError(fmt.Sprintf("failed to describe file"), err)
}
}

Expand Down
52 changes: 21 additions & 31 deletions pkg/kyverno/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,62 +22,52 @@ import (
)

// GetPolicies - Extracting the policies from multiple YAML
func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) {
func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, errors []error) {
for _, path := range paths {
path = filepath.Clean(path)
fileDesc, err := os.Stat(path)
if err != nil {
return nil, err
errors = append(errors, err)
continue
}

if fileDesc.IsDir() {
files, err := ioutil.ReadDir(path)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to parse %v", path), err)
errors = append(errors, fmt.Errorf("failed to read %v: %v", path, err.Error()))
continue
}

listOfFiles := make([]string, 0)
for _, file := range files {
listOfFiles = append(listOfFiles, filepath.Join(path, file.Name()))
}
policiesFromDir, err := GetPolicies(listOfFiles)

policiesFromDir, errrosFromDir := GetPolicies(listOfFiles)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to extract policies from %v", listOfFiles), err)
errors = append(errors, errrosFromDir...)
continue
}

policies = append(policies, policiesFromDir...)
} else {
file, err := ioutil.ReadFile(path)
fileBytes, err := ioutil.ReadFile(path)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to load file %v", path), err)
}
getPolicies, getErrors := utils.GetPolicy(file)
var errString string
for _, err := range getErrors {
if err != nil {
errString += err.Error() + "\n"
}
errors = append(errors, fmt.Errorf("failed to read %v: %v", path, err.Error()))
continue
}
if errString != "" {
fmt.Printf("failed to extract policies: %s\n", errString)
os.Exit(2)

policiesFromFile, errorsFromFile := utils.GetPolicy(fileBytes)
if errorsFromFile != nil {
errors = append(errors, errorsFromFile...)
continue
}

policies = append(policies, getPolicies...)
policies = append(policies, policiesFromFile...)
}
}

return policies, nil
}

//ValidateAndGetPolicies - validating policies
func ValidateAndGetPolicies(policyPaths []string) ([]*v1.ClusterPolicy, error) {
policies, err := GetPolicies(policyPaths)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return nil, sanitizederror.NewWithError((fmt.Sprintf("failed to parse %v path/s.", policyPaths)), err)
}
return nil, err
}
return policies, nil
return policies, errors
}

// PolicyHasVariables - check for variables in the policy
Expand Down
16 changes: 12 additions & 4 deletions pkg/kyverno/sanitizedError/error.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sanitizederror

import "fmt"
import (
"fmt"
"strings"
)

type customError struct {
message string
Expand All @@ -10,9 +13,14 @@ func (c customError) Error() string {
return c.message
}

// New creates a new sanitized error with given message
func New(message string) error {
return customError{message: message}
func NewWithErrors(message string, errors []error) error {
bldr := strings.Builder{}
bldr.WriteString(message + "\n")
for _, err := range errors {
bldr.WriteString(err.Error() + "\n")
}

return fmt.Errorf(bldr.String())
}

// NewWithError creates a new sanitized error with given message and error
Expand Down
Loading

0 comments on commit c766512

Please sign in to comment.