1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-29 10:55:05 +00:00

- handle operation remove case: if path does not exist - remove duplicate log - support validate in CLI

This commit is contained in:
shuting 2019-05-20 15:14:01 -07:00
parent fae1a4b058
commit 91b7a1b9ac
5 changed files with 55 additions and 37 deletions

View file

@ -13,6 +13,7 @@ import (
func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) ([]mutation.PatchBytes, []byte) {
var policyPatches []mutation.PatchBytes
var processedPatches []mutation.PatchBytes
var err error
patchedDocument := rawResource
for _, rule := range policy.Spec.Rules {

View file

@ -29,6 +29,9 @@ func ProcessPatches(patches []kubepolicy.Patch, resource []byte) ([]PatchBytes,
patchedDocument, err = applyPatch(patchedDocument, patchRaw)
if err != nil {
// TODO: continue on error if one of the patches fails, will add the failure event in such case
if patch.Operation == "remove" {
continue
}
log.Printf("Patch failed: patch number = %d, patch Operation = %s, err: %v", i, patch.Operation, err)
continue
}
@ -66,5 +69,9 @@ func applyPatch(resource []byte, patchRaw []byte) ([]byte, error) {
return nil, err
}
return patch.Apply(resource)
patchedDocument, err := patch.Apply(resource)
if err != nil {
return resource, err
}
return patchedDocument, err
}

View file

@ -35,7 +35,7 @@ const endpointsDocument string = `{
func TestProcessPatches_EmptyPatches(t *testing.T) {
var empty []types.Patch
patches, err := ProcessPatches(empty, []byte(endpointsDocument))
patches, _, err := ProcessPatches(empty, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patches) == 0)
}
@ -51,13 +51,13 @@ func makeAddIsMutatedLabelPatch() types.Patch {
func TestProcessPatches_EmptyDocument(t *testing.T) {
var patches []types.Patch
patches = append(patches, makeAddIsMutatedLabelPatch())
patchesBytes, err := ProcessPatches(patches, nil)
patchesBytes, _, err := ProcessPatches(patches, nil)
assert.Assert(t, err != nil)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AllEmpty(t *testing.T) {
patchesBytes, err := ProcessPatches(nil, nil)
patchesBytes, _, err := ProcessPatches(nil, nil)
assert.Assert(t, err != nil)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -66,7 +66,7 @@ func TestProcessPatches_AddPathDoesntExist(t *testing.T) {
patch := makeAddIsMutatedLabelPatch()
patch.Path = "/metadata/additional/is-mutated"
patches := []types.Patch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
patchesBytes, _, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -74,7 +74,7 @@ func TestProcessPatches_AddPathDoesntExist(t *testing.T) {
func TestProcessPatches_RemovePathDoesntExist(t *testing.T) {
patch := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patches := []types.Patch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
patchesBytes, _, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -83,7 +83,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_EmptyResult(t *testing.T) {
patch1 := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.Patch{Path: "/spec/labels/label3", Operation: "add", Value: "label3Value"}
patches := []types.Patch{patch1, patch2}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
patchesBytes, _, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -93,7 +93,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_NotEmptyResul
patch2 := types.Patch{Path: "/spec/labels/label2", Operation: "remove", Value: "label2Value"}
patch3 := types.Patch{Path: "/metadata/labels/label3", Operation: "add", Value: "label3Value"}
patches := []types.Patch{patch1, patch2, patch3}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
patchesBytes, _, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 1)
assertEqStringAndData(t, `{"path":"/metadata/labels/label3","op":"add","value":"label3Value"}`, patchesBytes[0])
@ -102,7 +102,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_NotEmptyResul
func TestProcessPatches_RemovePathDoesntExist_EmptyResult(t *testing.T) {
patch := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patches := []types.Patch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
patchesBytes, _, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -111,7 +111,7 @@ func TestProcessPatches_RemovePathDoesntExist_NotEmptyResult(t *testing.T) {
patch1 := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.Patch{Path: "/metadata/labels/label2", Operation: "add", Value: "label2Value"}
patches := []types.Patch{patch1, patch2}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
patchesBytes, _, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 1)
assertEqStringAndData(t, `{"path":"/metadata/labels/label2","op":"add","value":"label2Value"}`, patchesBytes[0])

View file

@ -56,7 +56,6 @@ func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVers
}
}
log.Println("Validation is successful")
return nil
}

View file

@ -27,32 +27,7 @@ func NewCmdApply(in io.Reader, out, errout io.Writer) *cobra.Command {
Short: "Apply policy on the resource",
Example: applyExample,
Run: func(cmd *cobra.Command, args []string) {
// TODO: add pre-checks for policy and resource manifest
// order for policy and resource in args could be disordered
if len(args) != 2 {
log.Printf("Missing policy and/or resource manifest.")
return
}
// extract policy
policyDir := validateDir(args[0])
policy, err := extractPolicy(policyDir)
if err != nil {
log.Printf("failed to extract policy: %v", err)
os.Exit(1)
}
// fmt.Printf("policy name=%s, rule name=%s, %s/%s\n", policy.ObjectMeta.Name, policy.Spec.Rules[0].Name,
// policy.Spec.Rules[0].ResourceDescription.Kind, *policy.Spec.Rules[0].ResourceDescription.Name)
// extract rawResource
resourceDir := validateDir(args[1])
rawResource, gvk, err := extractResource(resourceDir)
if err != nil {
log.Printf("failed to load resource: %v", err)
os.Exit(1)
}
policy, rawResource, gvk := complete(args)
_, patchedDocument := engine.Mutate(*policy, rawResource, *gvk)
out, err := prettyPrint(patchedDocument)
@ -62,12 +37,48 @@ func NewCmdApply(in io.Reader, out, errout io.Writer) *cobra.Command {
return
}
if err := engine.Validate(*policy, rawResource, *gvk); err != nil {
fmt.Println(err)
return
}
fmt.Printf("%v\n", string(out))
},
}
return cmd
}
func complete(args []string) (*kubepolicy.Policy, []byte, *metav1.GroupVersionKind) {
// TODO: add pre-checks for policy and resource manifest
// order for policy and resource in args could be disordered
if len(args) != 2 {
log.Printf("Missing policy and/or resource manifest.")
return nil, nil, nil
}
// extract policy
policyDir := validateDir(args[0])
policy, err := extractPolicy(policyDir)
if err != nil {
log.Printf("failed to extract policy: %v", err)
os.Exit(1)
}
// fmt.Printf("policy name=%s, rule name=%s, %s/%s\n", policy.ObjectMeta.Name, policy.Spec.Rules[0].Name,
// policy.Spec.Rules[0].ResourceDescription.Kind, *policy.Spec.Rules[0].ResourceDescription.Name)
// extract rawResource
resourceDir := validateDir(args[1])
rawResource, gvk, err := extractResource(resourceDir)
if err != nil {
log.Printf("failed to load resource: %v", err)
os.Exit(1)
}
return policy, rawResource, gvk
}
func extractPolicy(fileDir string) (*kubepolicy.Policy, error) {
policy := &kubepolicy.Policy{}