diff --git a/pkg/kyverno/apply/command.go b/pkg/kyverno/apply/command.go index a09bf6a826..302a757365 100644 --- a/pkg/kyverno/apply/command.go +++ b/pkg/kyverno/apply/command.go @@ -3,17 +3,17 @@ package apply import ( "bufio" "encoding/json" - "errors" "fmt" - "github.com/kyverno/kyverno/pkg/engine/response" "io/ioutil" "os" "path/filepath" "reflect" - yaml1 "sigs.k8s.io/yaml" "strings" "time" + "github.com/kyverno/kyverno/pkg/engine/response" + yaml1 "sigs.k8s.io/yaml" + v1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1" client "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" @@ -75,12 +75,10 @@ func Command() *cobra.Command { } }() - // base validations if valuesFile != "" && variablesString != "" { return sanitizedError.NewWithError("pass the values either using set flag or values_file flag", err) } - // get the variable values from from (-s) param / valuesFile (-f) variables, valuesMap, err := getVariable(variablesString, valuesFile) if err != nil { if !sanitizedError.IsErrorSanitized(err) { @@ -110,7 +108,7 @@ func Command() *cobra.Command { return sanitizedError.NewWithError(fmt.Sprintf("policy file(s) or cluster required"), err) } - policies, policiesFromCluster, err := common.ValidateAndGetPolicies(policyPaths, cluster, dClient, namespace) + policies, err := common.ValidateAndGetPolicies(policyPaths) if err != nil { if !sanitizedError.IsErrorSanitized(err) { return sanitizedError.NewWithError("failed to mutate policies.", err) @@ -130,7 +128,7 @@ func Command() *cobra.Command { return err } - resources, resourceFromCluster, err := getResourceAccordingToResourcePath(resourcePaths, cluster, policies, dClient, namespace) + resources, err := getResourceAccordingToResourcePath(resourcePaths, cluster, policies, dClient, namespace) if err != nil { if !sanitizedError.IsErrorSanitized(err) { return sanitizedError.NewWithError("failed to load resources", err) @@ -138,10 +136,6 @@ func Command() *cobra.Command { return err } - if policiesFromCluster == true && resourceFromCluster == false { - return sanitizedError.NewWithError("resource should be inside cluster", errors.New("policy is inside cluster and resource is outside cluster")) - } - mutatedPolicies, err := mutatePolices(policies) msgPolicies := "1 policy" @@ -201,7 +195,7 @@ func Command() *cobra.Command { } } - printReportOrViolation(policyReport , engineResponses , rc , resourcePaths) + printReportOrViolation(policyReport, engineResponses, rc, resourcePaths) return nil }, @@ -256,7 +250,7 @@ func getVariable(variablesString, valuesFile string) (variables map[string]strin } // checkMutateLogPath - checking path for printing mutated resource (-o flag) -func checkMutateLogPath(mutateLogPath string) (mutateLogPathIsDir bool, err error){ +func checkMutateLogPath(mutateLogPath string) (mutateLogPathIsDir bool, err error) { if mutateLogPath != "" { spath := strings.Split(mutateLogPath, "/") sfileName := strings.Split(spath[len(spath)-1], ".") @@ -278,7 +272,7 @@ func checkMutateLogPath(mutateLogPath string) (mutateLogPathIsDir bool, err erro } // getResourceAccordingToResourcePath - get resources according to the resource path -func getResourceAccordingToResourcePath(resourcePaths []string, cluster bool, policies []*v1.ClusterPolicy, dClient *client.Client, namespace string)(resources []*unstructured.Unstructured, resourceFromCluster bool, err error){ +func getResourceAccordingToResourcePath(resourcePaths []string, cluster bool, policies []*v1.ClusterPolicy, dClient *client.Client, namespace string) (resources []*unstructured.Unstructured, err error) { if len(resourcePaths) > 0 && resourcePaths[0] == "-" { if common.IsInputFromPipe() { resourceStr := "" @@ -290,30 +284,24 @@ func getResourceAccordingToResourcePath(resourcePaths []string, cluster bool, po yamlBytes := []byte(resourceStr) resources, err = common.GetResource(yamlBytes) if err != nil { - return resources, resourceFromCluster, 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 { - resources, resourceFromCluster, err = common.GetResources(policies, resourcePaths, dClient, cluster, namespace) + resources, err = common.GetResources(policies, resourcePaths, dClient, cluster, namespace) if err != nil { - return resources, resourceFromCluster, sanitizedError.NewWithError("failed to load resources", err) + return resources, sanitizedError.NewWithError("failed to load resources", err) } } - return resources, resourceFromCluster, err + return resources, err } // printReportOrViolation - printing policy report/violations -func printReportOrViolation(policyReport bool, engineResponses []response.EngineResponse , rc *resultCounts, resourcePaths []string){ +func printReportOrViolation(policyReport bool, engineResponses []response.EngineResponse, rc *resultCounts, resourcePaths []string) { if policyReport { resps := buildPolicyReports(engineResponses) if len(resps) > 0 { fmt.Println("----------------------------------------------------------------------\nPOLICY REPORT:") - //for _, u := range resps { - // fmt.Println("----------------------------------------------------------------------") - // yamlResp, _ := yaml1.Marshal(u) - // fmt.Println(string(yamlResp)) - //} - //fmt.Println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") report, _ := generateCLIraw(resps) yamlReport, _ := yaml1.Marshal(report) fmt.Println(string(yamlReport)) @@ -337,14 +325,13 @@ func printReportOrViolation(policyReport bool, engineResponses []response.Engine } // applyPolicyOnResource - function to apply policy on resource -func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, mutateLogPath string, mutateLogPathIsDir bool, variables map[string]string, rc *resultCounts, policyReport bool) ([]response.EngineResponse , error) { +func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, mutateLogPath string, mutateLogPathIsDir bool, variables map[string]string, rc *resultCounts, policyReport bool) ([]response.EngineResponse, error) { responseError := false engineResponses := make([]response.EngineResponse, 0) resPath := fmt.Sprintf("%s/%s/%s", resource.GetNamespace(), resource.GetKind(), resource.GetName()) log.Log.V(3).Info("applying policy on resource", "policy", policy.Name, "resource", resPath) - // build context ctx := context.NewContext() for key, value := range variables { startString := "" diff --git a/pkg/kyverno/apply/generate.go b/pkg/kyverno/apply/generate.go index 675d8e1243..3869b89d29 100644 --- a/pkg/kyverno/apply/generate.go +++ b/pkg/kyverno/apply/generate.go @@ -129,11 +129,6 @@ func updateSummary(results []interface{}) map[string]interface{} { switch typedResult["status"].(string) { case report.StatusPass: - //resources, ok := typedResult["resources"].([]interface{}) - //if !ok { - // continue - //} - pass, _ := summary["Pass"].(int64) pass++ summary["Pass"] = pass diff --git a/pkg/kyverno/apply/report.go b/pkg/kyverno/apply/report.go index 049fa6c461..a0e3d1e4bf 100644 --- a/pkg/kyverno/apply/report.go +++ b/pkg/kyverno/apply/report.go @@ -107,7 +107,6 @@ func buildPolicyResults(resps []response.EngineResponse) map[string][]*report.Po } } - //return mergeSucceededResults(results) return results } diff --git a/pkg/kyverno/common/common.go b/pkg/kyverno/common/common.go index f993561886..42d34fb29a 100644 --- a/pkg/kyverno/common/common.go +++ b/pkg/kyverno/common/common.go @@ -17,160 +17,68 @@ import ( jsonpatch "github.com/evanphx/json-patch" "github.com/go-logr/logr" v1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1" - client "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/kyverno/sanitizedError" "github.com/kyverno/kyverno/pkg/policymutation" "github.com/kyverno/kyverno/pkg/utils" ) // GetPolicies - Extracting the policies from multiple YAML -func GetPolicies(paths []string, cluster bool, dClient *client.Client, namespace string) (policies []*v1.ClusterPolicy, policiesFromCluster bool, error error) { - if len(paths) == 0 { - // get the policies from the cluster based on the scope - ps, err := getPoliciesFromCluster(cluster, dClient, namespace) +func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) { + for _, path := range paths { + path = filepath.Clean(path) + fileDesc, err := os.Stat(path) if err != nil { - return policies, policiesFromCluster, sanitizedError.NewWithError(fmt.Sprintf("error occurred while fetching policy from cluster. Path: %v", paths), err) + return nil, err } - policiesFromCluster = true - return ps, policiesFromCluster, nil - } else { - for _, path := range paths { - path = filepath.Clean(path) - fileDesc, err := os.Stat(path) + if fileDesc.IsDir() { + files, err := ioutil.ReadDir(path) if err != nil { - p, err := getPolicyFromCluster(path, cluster, dClient, namespace) - if err != nil { - return nil, policiesFromCluster, sanitizedError.NewWithError(fmt.Sprintf("error occurred while fetching policy from cluster. Path: %v", path), err) - } - policies = append(policies, p) - policiesFromCluster = true - continue + return nil, sanitizedError.NewWithError(fmt.Sprintf("failed to parse %v", path), err) } - if fileDesc.IsDir() { - files, err := ioutil.ReadDir(path) - if err != nil { - return nil, policiesFromCluster, sanitizedError.NewWithError(fmt.Sprintf("failed to parse %v", path), err) - } - listOfFiles := make([]string, 0) - for _, file := range files { - listOfFiles = append(listOfFiles, filepath.Join(path, file.Name())) - } - policiesFromDir, policiesFromCluster, err := GetPolicies(listOfFiles, cluster, dClient, namespace) - if err != nil { - return nil, policiesFromCluster, sanitizedError.NewWithError(fmt.Sprintf("failed to extract policies from %v", listOfFiles), err) - } - - policies = append(policies, policiesFromDir...) - } else { - file, err := ioutil.ReadFile(path) - if err != nil { - // check if cluster flag is passed and get the policy from cluster - p, err := getPolicyFromCluster(path, cluster, dClient, namespace) - if err != nil { - return nil, policiesFromCluster, sanitizedError.NewWithError(fmt.Sprintf("error occurred while fetching policy from cluster. Path: %v", path), err) - } - policies = append(policies, p) - policiesFromCluster = true - continue - } - getPolicies, getErrors := utils.GetPolicy(file) - var errString string - for _, err := range getErrors { - if err != nil { - errString += err.Error() + "\n" - } - } - if errString != "" { - fmt.Printf("failed to extract policies: %s\n", errString) - os.Exit(2) - } - - policies = append(policies, getPolicies...) + listOfFiles := make([]string, 0) + for _, file := range files { + listOfFiles = append(listOfFiles, filepath.Join(path, file.Name())) } - } - } - - return policies, policiesFromCluster, nil -} - -func getPolicyFromCluster(policyName string, cluster bool, dClient *client.Client, namespace string) (*v1.ClusterPolicy, error) { - if !cluster { - return &v1.ClusterPolicy{}, nil - } - - //check here---------------------------------- - kind := "ClusterPolicy" - policy, err := dClient.GetResource("", kind, namespace, policyName, "") - fmt.Println("------------policy : ", policy) - if err != nil { - fmt.Println("could not find clusterpolicy ... checking policy") - // try getting policy - kind := "Policy" - policy, err = dClient.GetResource("", kind, namespace, policyName, "") - if err != nil { - fmt.Println("error occurred while fetching policy", err) - return &v1.ClusterPolicy{}, err - } - } - - policyBytes, err := json.Marshal(policy.Object) - if err != nil { - return &v1.ClusterPolicy{}, sanitizedError.NewWithError(fmt.Sprintf("failed to marshal"), err) - } - - var p v1.ClusterPolicy - err = json.Unmarshal(policyBytes, &p) - - if err != nil { - return &v1.ClusterPolicy{}, sanitizedError.NewWithError(fmt.Sprintf("failed to unmarshal"), err) - } - - return &p, nil -} - -func getPoliciesFromCluster(cluster bool, dClient *client.Client, namespace string) ([]*v1.ClusterPolicy, error) { - res := make([]*v1.ClusterPolicy, 0) - if !cluster { - return res, nil - } - - policyTypes := []string{"ClusterPolicy", "Policy"} - for _, policy := range policyTypes { - policyList, err := dClient.ListResource("", policy, namespace, nil) - if err != nil { - return res, err - } - - for _, policy := range policyList.Items { - policyBytes, err := json.Marshal(policy.Object) + policiesFromDir, err := GetPolicies(listOfFiles) if err != nil { - return res, err + return nil, sanitizedError.NewWithError(fmt.Sprintf("failed to extract policies from %v", listOfFiles), err) } - var p v1.ClusterPolicy - err = json.Unmarshal(policyBytes, &p) - + policies = append(policies, policiesFromDir...) + } else { + file, err := ioutil.ReadFile(path) if err != nil { - return res, err + 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" + } + } + if errString != "" { + fmt.Printf("failed to extract policies: %s\n", errString) + os.Exit(2) } - res = append(res, &p) + policies = append(policies, getPolicies...) } } - return res, nil + return policies, nil } //ValidateAndGetPolicies - validating policies -func ValidateAndGetPolicies(policyPaths []string, cluster bool, dClient *client.Client, namespace string) ([]*v1.ClusterPolicy, bool, error) { - policies, policiesFromCluster, err := GetPolicies(policyPaths, cluster, dClient, namespace) +func ValidateAndGetPolicies(policyPaths []string) ([]*v1.ClusterPolicy, error) { + policies, err := GetPolicies(policyPaths) if err != nil { if !sanitizedError.IsErrorSanitized(err) { - return nil, policiesFromCluster, sanitizedError.NewWithError((fmt.Sprintf("failed to parse %v path/s.", policyPaths)), err) + return nil, sanitizedError.NewWithError((fmt.Sprintf("failed to parse %v path/s.", policyPaths)), err) } - return nil, policiesFromCluster, err + return nil, err } - return policies, policiesFromCluster, nil + return policies, nil } // PolicyHasVariables - check for variables in the policy diff --git a/pkg/kyverno/common/fetch.go b/pkg/kyverno/common/fetch.go index a2b7b8a8fe..b6f0d4f8f1 100644 --- a/pkg/kyverno/common/fetch.go +++ b/pkg/kyverno/common/fetch.go @@ -19,10 +19,9 @@ import ( // the resources are fetched from // - local paths to resources, if given // - the k8s cluster, if given -func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient *client.Client, cluster bool, namespace string) ([]*unstructured.Unstructured, bool, error) { +func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient *client.Client, cluster bool, namespace string) ([]*unstructured.Unstructured, error) { resources := make([]*unstructured.Unstructured, 0) var err error - var resourceFromCluster bool var resourceTypesMap = make(map[string]bool) var resourceTypes []string @@ -42,7 +41,7 @@ func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient if cluster && dClient != nil { resourceMap, err = getResourcesOfTypeFromCluster(resourceTypes, dClient, namespace) if err != nil { - return nil, resourceFromCluster, err + return nil, err } if len(resourcePaths) == 0 { for _, rm := range resourceMap { @@ -50,9 +49,6 @@ func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient resources = append(resources, rr) } } - if resources != nil{ - resourceFromCluster = true - } } } @@ -68,7 +64,6 @@ func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient if cluster { for _, rm := range resourceMap { for rn, rr := range rm { - resourceFromCluster = true if rn == resourcePath { resources = append(resources, rr) continue @@ -76,19 +71,19 @@ func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient } } } else { - return nil, resourceFromCluster, err + return nil, err } } getResources, err := GetResource(resourceBytes) if err != nil { - return nil, resourceFromCluster, err + return nil, err } for _, resource := range getResources { resources = append(resources, resource) } } - return resources, resourceFromCluster, nil + return resources, nil } func getResourceFromCluster(resourceTypes []string, resourceName string, dClient *client.Client) (*unstructured.Unstructured, error) { diff --git a/pkg/kyverno/validate/command.go b/pkg/kyverno/validate/command.go index 372b3acab7..4b4d8625b3 100644 --- a/pkg/kyverno/validate/command.go +++ b/pkg/kyverno/validate/command.go @@ -21,7 +21,6 @@ import ( log "sigs.k8s.io/controller-runtime/pkg/log" yaml "sigs.k8s.io/yaml" - client "github.com/kyverno/kyverno/pkg/dclient" ) func Command() *cobra.Command { @@ -77,9 +76,7 @@ func Command() *cobra.Command { } } } else { - cluster := false - var dClient *client.Client - policies, _, err = common.ValidateAndGetPolicies(policyPaths, cluster, dClient, "") + policies, err = common.ValidateAndGetPolicies(policyPaths) if err != nil { if !sanitizedError.IsErrorSanitized(err) { return sanitizedError.NewWithError("failed to mutate policies.", err)