1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-04-08 18:15:48 +00:00

added update logic in ResourceMutation

This commit is contained in:
NoSkillGirl 2020-12-30 00:12:36 +05:30
parent c66e2a7058
commit fabe9ee8aa
3 changed files with 75 additions and 54 deletions

View file

@ -410,7 +410,7 @@ func applyRule(log logr.Logger, client *dclient.Client, rule kyverno.Rule, resou
newResource.SetLabels(label)
_, err := client.UpdateResource(genAPIVersion, genKind, genNamespace, newResource, false)
if err != nil {
logger.Error(err, "updating existing resource")
logger.Error(err, "failed to update resource")
return noGenResource, err
}
logger.V(2).Info("updated target resource")

View file

@ -2,6 +2,7 @@ package webhooks
import (
contextdefault "context"
"encoding/json"
"fmt"
"reflect"
"sort"
@ -31,62 +32,67 @@ func (ws *WebhookServer) HandleGenerate(request *v1beta1.AdmissionRequest, polic
logger := ws.log.WithValues("action", "generation", "uid", request.UID, "kind", request.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
logger.V(4).Info("incoming request")
var engineResponses []*response.EngineResponse
if request.Operation == v1beta1.Create || request.Operation == v1beta1.Update {
if len(policies) == 0 {
return
}
// convert RAW to unstructured
new, old, err := kyvernoutils.ExtractResources(nil, request)
if err != nil {
logger.Error(err, "failed to extract resource")
}
if len(policies) == 0 {
return
}
// convert RAW to unstructured
new, old, err := kyvernoutils.ExtractResources(nil, request)
if err != nil {
logger.Error(err, "failed to extract resource")
}
policyContext := engine.PolicyContext{
NewResource: new,
OldResource: old,
AdmissionInfo: userRequestInfo,
ExcludeGroupRole: dynamicConfig.GetExcludeGroupRole(),
ExcludeResourceFunc: ws.configHandler.ToFilter,
ResourceCache: ws.resCache,
JSONContext: ctx,
}
policyContext := engine.PolicyContext{
NewResource: new,
OldResource: old,
AdmissionInfo: userRequestInfo,
ExcludeGroupRole: dynamicConfig.GetExcludeGroupRole(),
ExcludeResourceFunc: ws.configHandler.ToFilter,
ResourceCache: ws.resCache,
JSONContext: ctx,
}
for _, policy := range policies {
var rules []response.RuleResponse
policyContext.Policy = *policy
engineResponse := engine.Generate(policyContext)
for _, rule := range engineResponse.PolicyResponse.Rules {
if !rule.Success {
ws.deleteGR(logger, engineResponse)
continue
for _, policy := range policies {
var rules []response.RuleResponse
policyContext.Policy = *policy
engineResponse := engine.Generate(policyContext)
for _, rule := range engineResponse.PolicyResponse.Rules {
if !rule.Success {
ws.deleteGR(logger, engineResponse)
continue
}
rules = append(rules, rule)
}
if len(rules) > 0 {
engineResponse.PolicyResponse.Rules = rules
// some generate rules do apply to the resource
engineResponses = append(engineResponses, engineResponse)
ws.statusListener.Update(generateStats{
resp: engineResponse,
})
}
rules = append(rules, rule)
}
if len(rules) > 0 {
engineResponse.PolicyResponse.Rules = rules
// some generate rules do apply to the resource
engineResponses = append(engineResponses, engineResponse)
ws.statusListener.Update(generateStats{
resp: engineResponse,
})
// Adds Generate Request to a channel(queue size 1000) to generators
if failedResponse := applyGenerateRequest(ws.grGenerator, userRequestInfo, request.Operation, engineResponses...); err != nil {
// report failure event
for _, failedGR := range failedResponse {
events := failedEvents(fmt.Errorf("failed to create Generate Request: %v", failedGR.err), failedGR.gr, new)
ws.eventGen.Add(events...)
}
}
}
// Adds Generate Request to a channel(queue size 1000) to generators
if failedResponse := applyGenerateRequest(ws.grGenerator, userRequestInfo, request.Operation, engineResponses...); err != nil {
// report failure event
for _, failedGR := range failedResponse {
events := failedEvents(fmt.Errorf("failed to create Generate Request: %v", failedGR.err), failedGR.gr, new)
ws.eventGen.Add(events...)
}
if request.Operation == v1beta1.Update {
ws.handleUpdate(request)
}
return
}
//HandleUpdateAndDelete handles admission-requests for delete and update
func (ws *WebhookServer) handleDeleteAndUpdate(request *v1beta1.AdmissionRequest) {
//HandleUpdate handles admission-requests for update
func (ws *WebhookServer) handleUpdate(request *v1beta1.AdmissionRequest) {
logger := ws.log.WithValues("action", "generation", "uid", request.UID, "kind", request.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
resource, err := enginutils.ConvertToUnstructured(request.OldObject.Raw)
if err != nil {
@ -94,14 +100,7 @@ func (ws *WebhookServer) handleDeleteAndUpdate(request *v1beta1.AdmissionRequest
}
resLabels := resource.GetLabels()
if resLabels["app.kubernetes.io/managed-by"] == "kyverno" && resLabels["policy.kyverno.io/synchronize"] == "enable" && request.Operation == v1beta1.Delete {
grName := resLabels["policy.kyverno.io/gr-name"]
gr, err := ws.grLister.Get(grName)
if err != nil {
logger.Error(err, "failed to get generate request", "name", grName)
}
ws.grController.EnqueueGenerateRequestFromWebhook(gr)
} else if resLabels["generate.kyverno.io/clone-policy-name"] != "" && request.Operation == v1beta1.Update {
if resLabels["generate.kyverno.io/clone-policy-name"] != "" {
policyNames := strings.Split(resLabels["generate.kyverno.io/clone-policy-name"], ",")
for _, policyName := range policyNames {
selector := labels.SelectorFromSet(labels.Set(map[string]string{
@ -120,6 +119,28 @@ func (ws *WebhookServer) handleDeleteAndUpdate(request *v1beta1.AdmissionRequest
}
}
//HandleDelete handles admission-requests for delete
func (ws *WebhookServer) handleDelete(request *v1beta1.AdmissionRequest) {
logger := ws.log.WithValues("action", "generation", "uid", request.UID, "kind", request.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
resource, err := enginutils.ConvertToUnstructured(request.OldObject.Raw)
if err != nil {
logger.Error(err, "failed to convert object resource to unstructured format")
}
r, _ := json.Marshal(resource)
fmt.Println(string(r))
resLabels := resource.GetLabels()
if resLabels["app.kubernetes.io/managed-by"] == "kyverno" && resLabels["policy.kyverno.io/synchronize"] == "enable" && request.Operation == v1beta1.Delete {
grName := resLabels["policy.kyverno.io/gr-name"]
gr, err := ws.grLister.Get(grName)
if err != nil {
logger.Error(err, "failed to get generate request", "name", grName)
}
ws.grController.EnqueueGenerateRequestFromWebhook(gr)
}
}
func (ws *WebhookServer) deleteGR(logger logr.Logger, engineResponse *response.EngineResponse) {
logger.V(4).Info("querying all generate requests")
selector := labels.SelectorFromSet(labels.Set(map[string]string{

View file

@ -377,8 +377,8 @@ func (ws *WebhookServer) ResourceMutation(request *v1beta1.AdmissionRequest) *v1
func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
logger := ws.log.WithName("Validate").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
if request.Operation == v1beta1.Delete || request.Operation == v1beta1.Update {
ws.handleDeleteAndUpdate(request)
if request.Operation == v1beta1.Delete {
ws.handleDelete(request)
}
if !ws.supportMutateValidate {