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

Change of annotation purpose #262

This commit is contained in:
Shuting Zhao 2019-08-19 16:10:10 -07:00
parent 998f612679
commit 4c34ff7a37
6 changed files with 129 additions and 11 deletions

View file

@ -56,11 +56,8 @@ func Mutate(policy kyverno.Policy, resource unstructured.Unstructured) EngineRes
ruleInfo.Addf("Rule %s: Overlay succesfully applied.", rule.Name)
// merge the json patches
patch := JoinPatches(rulePatches)
// strip slashes from string
ruleInfo.Changes = string(patch)
ruleInfo.Patches = rulePatches
allPatches = append(allPatches, rulePatches...)
glog.V(4).Infof("overlay applied succesfully on resource %s/%s", resource.GetNamespace(), resource.GetName())
@ -83,6 +80,8 @@ func Mutate(policy kyverno.Policy, resource unstructured.Unstructured) EngineRes
} else {
glog.V(4).Infof("patches applied succesfully on resource %s/%s", resource.GetNamespace(), resource.GetName())
ruleInfo.Addf("Patches succesfully applied.")
ruleInfo.Patches = rulePatches
allPatches = append(allPatches, rulePatches...)
}
}
@ -96,6 +95,11 @@ func Mutate(policy kyverno.Policy, resource unstructured.Unstructured) EngineRes
}
patchedResource, err := ConvertToUnstructured(patchedDocument)
if err != nil {
glog.Errorf("Failed to convert patched resource to unstructuredtype, err%v\n:", err)
return EngineResponse{PatchedResource: resource}
}
return EngineResponse{
Patches: allPatches,
PatchedResource: *patchedResource,

View file

@ -20,7 +20,7 @@ import (
func Validate(policy kyverno.Policy, resource unstructured.Unstructured) EngineResponse {
resourceRaw, err := resource.MarshalJSON()
if err != nil {
glog.V(4).Infof("unable to marshal resource : %v\n", err)
glog.V(4).Infof("Skip processing validating rule, unable to marshal resource : %v\n", err)
return EngineResponse{PatchedResource: resource}
}

View file

@ -104,7 +104,7 @@ type RuleInfo struct {
Name string
RuleType RuleType
Msgs []string
Changes string // this will store the mutation patch being applied by the rule
Patches [][]byte // this will store the mutation patch being applied by the rule
success bool
}

113
pkg/webhooks/annotations.go Normal file
View file

@ -0,0 +1,113 @@
package webhooks
import (
"encoding/json"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
jsonpatch "github.com/evanphx/json-patch"
"github.com/golang/glog"
"github.com/nirmata/kyverno/pkg/info"
)
const (
policyAnnotation = "policies.kyverno.io"
// lastAppliedPatches = policyAnnotation + "last-applied-patches"
)
type policyPatch struct {
PolicyName string `json:"policyname"`
// RulePatches []string `json:"patches"`
RulePatches interface{} `json:"patches"`
}
type rulePatch struct {
RuleName string `json:"rulename"`
Op string `json:"op"`
Path string `json:"path"`
}
type response struct {
Op string `json:"op"`
Path string `json:"path"`
Value interface{} `json:"value"`
}
func prepareAnnotationPatches(resource *unstructured.Unstructured, policyInfos []info.PolicyInfo) []byte {
annots := resource.GetAnnotations()
if annots == nil {
annots = map[string]string{}
}
var patchResponse response
value := annotationFromPolicies(policyInfos)
if _, ok := annots[policyAnnotation]; ok {
// create update patch string
patchResponse = response{
Op: "replace",
Path: "/metadata/annotations/" + policyAnnotation,
Value: string(value),
}
} else {
patchResponse = response{
Op: "add",
Path: "/metadata/annotations",
Value: map[string]string{policyAnnotation: string(value)},
}
}
patchByte, _ := json.Marshal(patchResponse)
// check the patch
_, err := jsonpatch.DecodePatch([]byte("[" + string(patchByte) + "]"))
if err != nil {
glog.Errorf("Failed to make patch from annotation'%s', err: %v\n ", string(patchByte), err)
}
return patchByte
}
func annotationFromPolicies(policyInfos []info.PolicyInfo) []byte {
var policyPatches []policyPatch
for _, policyInfo := range policyInfos {
var pp policyPatch
pp.PolicyName = policyInfo.Name
pp.RulePatches = annotationFromPolicy(policyInfo)
policyPatches = append(policyPatches, pp)
}
result, _ := json.Marshal(policyPatches)
return result
}
func annotationFromPolicy(policyInfo info.PolicyInfo) []rulePatch {
if !policyInfo.IsSuccessful() {
glog.V(2).Infof("Policy %s failed, skip preparing annotation\n", policyInfo.Name)
return nil
}
var rulePatches []rulePatch
for _, ruleInfo := range policyInfo.Rules {
for _, patch := range ruleInfo.Patches {
var patchmap map[string]string
if err := json.Unmarshal(patch, &patchmap); err != nil {
glog.Errorf("Failed to parse patch bytes, err: %v\n", err)
continue
}
rp := rulePatch{
RuleName: ruleInfo.Name,
Op: patchmap["op"],
Path: patchmap["path"]}
rulePatches = append(rulePatches, rp)
glog.V(4).Infof("Annotation value prepared: %v\n", rulePatches)
}
}
return rulePatches
}

View file

@ -62,18 +62,20 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool
}
continue
}
// build annotations per policy being applied to show the mutation changes
patches = append(patches, engineResponse.Patches...)
glog.V(4).Infof("Mutation from policy %s has applied succesfully to %s %s/%s", policy.Name, request.Kind.Kind, resource.GetNamespace(), resource.GetName())
patches = append(patches, engineResponse.Patches...)
policyInfos = append(policyInfos, policyInfo)
glog.V(4).Infof("Mutation from policy %s has applied succesfully to %s %s/%s", policy.Name, request.Kind.Kind, resource.GetNamespace(), resource.GetName())
}
// ADD ANNOTATIONS
// TODO: merge the annotation patch with the patch response
// ADD EVENTS
if len(patches) > 0 {
eventsInfo := newEventInfoFromPolicyInfo(policyInfos, (request.Operation == v1beta1.Update), info.Mutation)
ws.eventGen.Add(eventsInfo...)
annotation := prepareAnnotationPatches(resource, policyInfos)
patches = append(patches, annotation)
}
ok, msg := isAdmSuccesful(policyInfos)

View file

@ -52,7 +52,6 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, res
engineResponse := engine.Validate(*policy, resource)
if len(engineResponse.RuleInfos) == 0 {
glog.Errorln("Failed to process validate rule, error parsing rawResource")
continue
}