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:
parent
7fc0eaaee3
commit
ccdcb6ae89
6 changed files with 96 additions and 39 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue