1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

Feature/read from stdin validate (#1171)

* temp

* added pipe logic for validate

* fixed test cases - policy mutation
This commit is contained in:
Pooja Singh 2020-10-07 06:20:53 +05:30 committed by GitHub
parent 7fc0eaaee3
commit ccdcb6ae89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 39 deletions

View file

@ -40,19 +40,24 @@ yay -S kyverno-git
Prints the version of kyverno used by the CLI.
Example:
Example:
```
kyverno version
```
### Validate
Validates a policy, can validate multiple policy resource description files or even an entire folder containing policy resource description
files. Currently supports files with resource description in yaml.
files. Currently supports files with resource description in yaml. The policies can also be passed from stdin.
Example:
```
kyverno validate /path/to/policy1.yaml /path/to/policy2.yaml /path/to/folderFullOfPolicies
```
Passing policy from stdin:
```
kustomize build nginx/overlays/envs/prod/ | kyverno validate -
```
Use the -o <yaml/json> flag to display the mutated policy.

View file

@ -9,6 +9,7 @@ import (
"reflect"
"github.com/nirmata/kyverno/pkg/engine/context"
"github.com/nirmata/kyverno/pkg/openapi"
"k8s.io/apimachinery/pkg/util/yaml"
"os"
@ -151,7 +152,7 @@ func Command() *cobra.Command {
}
}
policies, openAPIController, err := common.GetPoliciesValidation(policyPaths)
policies, err := common.GetPoliciesValidation(policyPaths)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to mutate policies.", err)
@ -159,6 +160,11 @@ func Command() *cobra.Command {
return err
}
openAPIController, err := openapi.NewOpenAPIController()
if err != nil {
return sanitizedError.NewWithError("failed to initialize openAPIController", err)
}
var dClient *client.Client
if cluster {
restConfig, err := kubernetesConfig.ToRESTConfig()
@ -173,7 +179,7 @@ func Command() *cobra.Command {
var resources []*unstructured.Unstructured
if resourcePaths[0] == "-" {
if isInputFromPipe() {
if common.IsInputFromPipe() {
resourceStr := ""
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
@ -588,8 +594,3 @@ func createFileOrFolder(mutateLogPath string, mutateLogPathIsDir bool) error {
return nil
}
func isInputFromPipe() bool {
fileInfo, _ := os.Stdin.Stat()
return fileInfo.Mode()&os.ModeCharDevice == 0
}

View file

@ -20,7 +20,6 @@ import (
"github.com/go-logr/logr"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/kyverno/sanitizedError"
"github.com/nirmata/kyverno/pkg/openapi"
"github.com/nirmata/kyverno/pkg/policymutation"
"github.com/nirmata/kyverno/pkg/utils"
log "sigs.k8s.io/controller-runtime/pkg/log"
@ -57,7 +56,12 @@ func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) {
policies = append(policies, policiesFromDir...)
} else {
getPolicies, getErrors := utils.GetPolicy(path)
file, err := ioutil.ReadFile(path)
if err != nil {
log.Error(err, fmt.Sprintf("failed to load file: %v", path))
return nil, sanitizedError.NewWithError(("failed to load file"), err)
}
getPolicies, getErrors := utils.GetPolicy(file)
var errString string
for _, err := range getErrors {
if err != nil {
@ -78,21 +82,15 @@ func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) {
}
//GetPoliciesValidation - validating policies
func GetPoliciesValidation(policyPaths []string) ([]*v1.ClusterPolicy, *openapi.Controller, error) {
func GetPoliciesValidation(policyPaths []string) ([]*v1.ClusterPolicy, error) {
policies, err := GetPolicies(policyPaths)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return nil, nil, 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, nil, err
return nil, err
}
openAPIController, err := openapi.NewOpenAPIController()
if err != nil {
return nil, nil, err
}
return policies, openAPIController, nil
return policies, nil
}
// PolicyHasVariables - check for variables in the policy
@ -242,3 +240,9 @@ func GetCRD(path string) (unstructuredCrds []*unstructured.Unstructured, err err
return unstructuredCrds, nil
}
// IsInputFromPipe - check if input is passed using pipe
func IsInputFromPipe() bool {
fileInfo, _ := os.Stdin.Stat()
return fileInfo.Mode()&os.ModeCharDevice == 0
}

View file

@ -1,11 +1,14 @@
package validate
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"os"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/openapi"
"github.com/nirmata/kyverno/pkg/utils"
"github.com/nirmata/kyverno/pkg/kyverno/common"
@ -45,9 +48,46 @@ func Command() *cobra.Command {
}
}
policies, openAPIController, err := common.GetPoliciesValidation(policyPaths)
if len(policyPaths) == 0 {
return sanitizedError.NewWithError(fmt.Sprintf("policy file(s) required"), err)
}
var policies []*v1.ClusterPolicy
if policyPaths[0] == "-" {
if common.IsInputFromPipe() {
policyStr := ""
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
policyStr = policyStr + scanner.Text() + "\n"
}
yamlBytes := []byte(policyStr)
var getErrors []error
policies, getErrors = utils.GetPolicy(yamlBytes)
var errString string
for _, err := range getErrors {
if err != nil {
errString += err.Error() + "\n"
}
}
if errString != "" {
return sanitizedError.NewWithError("failed to extract the resources", errors.New(errString))
}
}
} else {
policies, err = common.GetPoliciesValidation(policyPaths)
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to mutate policies.", err)
}
return err
}
}
openAPIController, err := openapi.NewOpenAPIController()
if err != nil {
return err
return sanitizedError.NewWithError("failed to initialize openAPIController", err)
}
// if CRD's are passed, add these to OpenAPIController

View file

@ -1,6 +1,7 @@
package policymutation
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -25,8 +26,11 @@ func Test_Exclude(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
policies, errs := utils.GetPolicy(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
file, err := ioutil.ReadFile(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
policies, errs := utils.GetPolicy(file)
if len(errs) != 0 {
t.Log(errs)
}
@ -53,8 +57,11 @@ func Test_CronJobOnly(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
policies, errs := utils.GetPolicy(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
file, err := ioutil.ReadFile(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
policies, errs := utils.GetPolicy(file)
if len(errs) != 0 {
t.Log(errs)
}
@ -83,7 +90,11 @@ func Test_CronJob_hasExclude(t *testing.T) {
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
policies, errs := utils.GetPolicy(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
file, err := ioutil.ReadFile(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
policies, errs := utils.GetPolicy(file)
if len(errs) != 0 {
t.Log(errs)
}
@ -115,8 +126,11 @@ func Test_CronJobAndDeployment(t *testing.T) {
dir, err := os.Getwd()
baseDir := filepath.Dir(filepath.Dir(dir))
assert.NilError(t, err)
policies, errs := utils.GetPolicy(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
file, err := ioutil.ReadFile(baseDir + "/samples/best_practices/disallow_bind_mounts.yaml")
if err != nil {
t.Log(err)
}
policies, errs := utils.GetPolicy(file)
if len(errs) != 0 {
t.Log(errs)
}

View file

@ -6,20 +6,13 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"k8s.io/apimachinery/pkg/util/yaml"
)
// GetPolicy - Extracts policies from a YAML
func GetPolicy(path string) (clusterPolicies []*v1.ClusterPolicy, errors []error) {
file, err := ioutil.ReadFile(path)
if err != nil {
errors = append(errors, fmt.Errorf(fmt.Sprintf("failed to load file: %v. error: %v", path, err)))
return clusterPolicies, errors
}
func GetPolicy(file []byte) (clusterPolicies []*v1.ClusterPolicy, errors []error) {
policies, err := SplitYAMLDocuments(file)
if err != nil {
errors = append(errors, err)
@ -35,7 +28,7 @@ func GetPolicy(path string) (clusterPolicies []*v1.ClusterPolicy, errors []error
policy := &v1.ClusterPolicy{}
if err := json.Unmarshal(policyBytes, policy); err != nil {
errors = append(errors, fmt.Errorf(fmt.Sprintf("failed to decode policy in %s. error: %v", path, err)))
errors = append(errors, fmt.Errorf(fmt.Sprintf("failed to decode policy. error: %v", err)))
continue
}