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

revised 522 changes

This commit is contained in:
shravan 2020-01-23 20:19:58 +05:30
parent 344af84ec5
commit be8527be47

View file

@ -1,7 +1,6 @@
package policy
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
@ -9,9 +8,14 @@ import (
"strings"
"sync"
"github.com/nirmata/kyverno/pkg/engine"
"github.com/nirmata/kyverno/pkg/engine/context"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
"github.com/googleapis/gnostic/compiler"
"github.com/nirmata/kyverno/pkg/engine/utils"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kube-openapi/pkg/util/proto/validation"
@ -25,9 +29,7 @@ var validationGlobalState struct {
isSet bool
}
func ValidateMutationPatches(kind string, policyPatch []byte) error {
kind = "io.k8s.api.core.v1." + kind
func ValidatePolicyMutation(policy v1.ClusterPolicy) error {
if validationGlobalState.isSet == false {
err := setValidationGlobalState()
if err != nil {
@ -35,18 +37,56 @@ func ValidateMutationPatches(kind string, policyPatch []byte) error {
}
}
emptyResourceObject := generateEmptyResource(validationGlobalState.definitions[kind])
emptyResourceObjectRaw, err := json.Marshal(emptyResourceObject)
if err != nil {
return err
var allPossibleKinds = make(map[string]bool)
for _, rule := range policy.Spec.Rules {
if rule.HasMutate() {
for _, kind := range rule.MatchResources.Kinds {
allPossibleKinds[kind] = true
}
}
}
patchedResource, err := utils.ApplyPatchNew(emptyResourceObjectRaw, policyPatch)
if err != nil {
return err
for kind := range allPossibleKinds {
resource, _ := generateEmptyResource(validationGlobalState.definitions[kind]).(map[string]interface{})
newResource := unstructured.Unstructured{Object: resource}
policyContext := engine.PolicyContext{
Policy: policy,
NewResource: newResource,
Context: context.NewContext(),
}
resp := engine.Mutate(policyContext)
err := ValidateResource(resp.PatchedResource.UnstructuredContent(), kind)
if err != nil {
return err
}
}
return validateResource(patchedResource, kind)
return nil
}
func ValidateResource(patchedResource interface{}, kind string) error {
if validationGlobalState.isSet == false {
err := setValidationGlobalState()
if err != nil {
return err
}
}
schema := validationGlobalState.models.LookupModel(kind)
if schema == nil {
return fmt.Errorf("pre-validation: couldn't find model %s", kind)
}
if errs := validation.ValidateModel(patchedResource, schema, kind); len(errs) > 0 {
var errorMessages []string
for i := range errs {
errorMessages = append(errorMessages, errs[i].Error())
}
return fmt.Errorf(strings.Join(errorMessages, "\n\n"))
}
return nil
}
func setValidationGlobalState() error {
@ -90,29 +130,6 @@ func getSchemaDocument(path string) (*openapi_v2.Document, error) {
return openapi_v2.NewDocument(spec, compiler.NewContext("$root", nil))
}
func validateResource(patchedResourceRaw []byte, kind string) error {
var patchedResource interface{}
if err := json.Unmarshal(patchedResourceRaw, &patchedResource); err != nil {
return fmt.Errorf("pre-validation: failed to parse yaml: %v", err)
}
schema := validationGlobalState.models.LookupModel(kind)
if schema == nil {
return fmt.Errorf("pre-validation: couldn't find model %s", kind)
}
if errs := validation.ValidateModel(patchedResource, schema, kind); len(errs) > 0 {
var errorMessages []string
for i := range errs {
errorMessages = append(errorMessages, errs[i].Error())
}
return fmt.Errorf(strings.Join(errorMessages, "\n\n"))
}
return nil
}
func generateEmptyResource(kindSchema *openapi_v2.Schema) interface{} {
types := kindSchema.GetType().GetValue()