Skip to content

Commit

Permalink
Revert "ignore non-policy files while loading"
Browse files Browse the repository at this point in the history
This reverts commit c766512.
  • Loading branch information
JimBugwadia committed Dec 6, 2020
1 parent c766512 commit a649151
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 140 deletions.
71 changes: 27 additions & 44 deletions pkg/engine/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package engine
import (
"fmt"
"reflect"
"strings"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -247,35 +246,43 @@ func isSameRules(oldRules []response.RuleResponse, newRules []response.RuleRespo
// validatePatterns validate pattern and anyPattern
func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstructured.Unstructured, rule kyverno.Rule) (resp response.RuleResponse) {
startTime := time.Now()
logger := log.WithValues("rule", rule.Name, "name", resource.GetName(), "kind", resource.GetKind())
logger := log.WithValues("rule", rule.Name)
logger.V(4).Info("start processing rule", "startTime", startTime)
resp.Name = rule.Name
resp.Type = utils.Validation.String()
defer func() {
resp.RuleStats.ProcessingTime = time.Since(startTime)
logger.V(3).Info("finished processing rule", "processingTime", resp.RuleStats.ProcessingTime.String())
logger.V(4).Info("finished processing rule", "processingTime", resp.RuleStats.ProcessingTime.String())
}()

// work on a copy of validation rule
validationRule := rule.Validation.DeepCopy()

// either pattern or anyPattern can be specified in Validation rule
if validationRule.Pattern != nil {
// substitute variables in the pattern
pattern := validationRule.Pattern
var err error
if pattern, err = variables.SubstituteVars(logger, ctx, pattern); err != nil {
// variable substitution failed
resp.Success = false
resp.Message = fmt.Sprintf("variable substitution failed for rule '%s'. '%s'", rule.Name, err)
resp.Message = fmt.Sprintf("Validation error: %s; Validation rule '%s' failed. '%s'",
rule.Validation.Message, rule.Name, err)
return resp
}

if path, err := validate.ValidateResourceWithPattern(logger, resource.Object, pattern); err != nil {
logger.V(3).Info("validation failed", "path", path, "error", err.Error())
// validation failed
logger.V(5).Info(err.Error())
resp.Success = false
resp.Message = buildErrorMessage(rule, path)
resp.Message = fmt.Sprintf("Validation error: %s; Validation rule %s failed at path %s",
rule.Validation.Message, rule.Name, path)
return resp
}

logger.V(4).Info("successfully processed rule")
resp.Success = true
resp.Message = fmt.Sprintf("validation rule '%s' passed.", rule.Name)
resp.Message = fmt.Sprintf("Validation rule '%s' succeeded.", rule.Name)
return resp
}

Expand All @@ -287,32 +294,31 @@ func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstr
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
if err != nil {
resp.Success = false
resp.Message = fmt.Sprintf("failed to deserialize anyPattern, expected type array: %v", err)
resp.Message = fmt.Sprintf("Failed to deserialize anyPattern, expect type array: %v", err)
return resp
}

for idx, pattern := range anyPatterns {
if pattern, err = variables.SubstituteVars(logger, ctx, pattern); err != nil {
// variable substitution failed
failedSubstitutionsErrors = append(failedSubstitutionsErrors, err)
continue
}

path, err := validate.ValidateResourceWithPattern(logger, resource.Object, pattern)
_, err := validate.ValidateResourceWithPattern(logger, resource.Object, pattern)
if err == nil {
resp.Success = true
resp.Message = fmt.Sprintf("validation rule '%s' anyPattern[%d] passed.", rule.Name, idx)
resp.Message = fmt.Sprintf("Validation rule '%s' anyPattern[%d] succeeded.", rule.Name, idx)
return resp
}

logger.V(4).Info("validation rule failed", "anyPattern[%d]", idx, "path", path)
patternErr := fmt.Errorf("Rule %s[%d] failed at path %s.", rule.Name, idx, path)
logger.V(4).Info(fmt.Sprintf("validation rule failed for anyPattern[%d]", idx), "message", rule.Validation.Message)
patternErr := fmt.Errorf("anyPattern[%d] failed; %s", idx, err)
failedAnyPatternsErrors = append(failedAnyPatternsErrors, patternErr)
}

// Substitution failures
if len(failedSubstitutionsErrors) > 0 {
resp.Success = false
resp.Message = fmt.Sprintf("failed to substitute variables: %v", failedSubstitutionsErrors)
resp.Message = fmt.Sprintf("Substitutions failed: %v", failedSubstitutionsErrors)
return resp
}

Expand All @@ -322,38 +328,15 @@ func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstr
for _, err := range failedAnyPatternsErrors {
errorStr = append(errorStr, err.Error())
}

log.V(4).Info(fmt.Sprintf("Validation rule '%s' failed. %s", rule.Name, errorStr))

resp.Success = false
resp.Message = buildAnyPatternErrorMessage(rule, errorStr)
log.V(4).Info(fmt.Sprintf("Validation rule '%s' failed. %s", rule.Name, errorStr))
if rule.Validation.Message == "" {
resp.Message = fmt.Sprintf("Validation rule '%s' has failed", rule.Name)
} else {
resp.Message = rule.Validation.Message
}
return resp
}
}
return response.RuleResponse{}
}

func buildErrorMessage(rule kyverno.Rule, path string) string {
if rule.Validation.Message == "" {
return fmt.Sprintf("validation error: rule %s failed at path %s", rule.Name, path)
}

if strings.HasSuffix(rule.Validation.Message, ".") {
return fmt.Sprintf("validation error: %s Rule %s failed at path %s", rule.Validation.Message, rule.Name, path)
}

return fmt.Sprintf("validation error: %s. Rule %s failed at path %s", rule.Validation.Message, rule.Name, path)
}

func buildAnyPatternErrorMessage(rule kyverno.Rule, errors []string) string {
errStr := strings.Join(errors, " ")
if rule.Validation.Message == "" {
return fmt.Sprintf("validation error: %s", errStr)
}

if strings.HasSuffix(rule.Validation.Message, ".") {
return fmt.Sprintf("validation error: %s %s", rule.Validation.Message, errStr)
}

return fmt.Sprintf("validation error: %s. %s", rule.Validation.Message, errStr)
}
95 changes: 48 additions & 47 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"
"github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
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,7 +59,18 @@ type SkippedPolicy struct {
Variable string `json:"variable"`
}

var applyHelp = `
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(`
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 @@ -101,46 +112,33 @@ To apply policy with variables:
<variable1 in policy2>: <value>
<variable2 in policy2>: <value>
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,
More info: https://kyverno.io/docs/kyverno-cli/
`),
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 @@ -156,30 +154,33 @@ func Command() *cobra.Command {
}

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

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

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 @@ -243,12 +244,12 @@ func Command() *cobra.Command {
}

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 @@ -284,17 +285,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 @@ -322,8 +323,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 @@ -344,7 +345,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 @@ -433,7 +434,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 @@ -502,8 +503,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 @@ -556,30 +557,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
Loading

0 comments on commit a649151

Please sign in to comment.