mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 07:57:07 +00:00
* add report in cli * policy report crd added * policy report added * configmap added * added jobs * added jobs * bug fixed * added logic for cli * common function added * sub command added for policy report * subcommand added for report * common package changed * configmap added * added logic for kyverno cli * added logic for jobs * added logic for jobs * added logic for jobs * added logic for cli * buf fix * cli changes * count bug fix * docs added for command * go fmt * refactor codebase * remove policy controller for policyreport * policy report removed * bug fixes * bug fixes * added job trigger if needed * job deletation logic added * build failed fix * fixed e2e test * remove hard coded variables * packages adde * improvment added in jobs sheduler * policy report yaml added * cronjob added * small fixes * remove background sync * documentation added for report command * remove extra log * small improvement * tested policy report * revert hardcoded changes * changes for demo * demo changes * resource aggrigation added * More changes * More changes * - resolve PR comments; - refactor jobs controller * set rbac for jobs * add clean up in job controller * add short names * remove application scope for policyreport * move job controller to policyreport * add report logic in command apply * - update policy report types; - upgrade k8s library; - update code gen * temporarily comment out code to pass CI build * generate / update policyreport to cluster * add unit test for CLI report * add test for apply - generate policy report * fix unit test * - remove job controller; - remove in-memory configmap; - clean up kustomize manifest * remove dependency * add reportRequest / clusterReportRequest * clean up policy report * generate report request * update crd clusterReportRequest * - update json tag of report summary; - update definition manifests; - fix dclient creation * aggregate reportRequest into policy report * fix unit tests * - update report summary to optional; - generate clusterPolicyReport; - remove reportRequests after merged to report * remove * generate reportRequest in kyverno namespace * update resource filter in helm chart * - rename reportRequest to reportChangeRequest; -rename clusterReportRequest to clusterReportChangeRequest * generate policy report in background scan * skip generating report change request if there's entry results * fix results entry removal when policy / rule gets deleted * rename apiversion from policy.kubernetes.io to policy.k8s.io * update summary.* to lower case * move reportChangeRequest to kyverno.io/v1alpha1 * remove policy report flag * fix report update * clean up policy violation CRD * remove violation CRD from manifest * clean up policy violation code - remove pvGenerator * change severity fields to lower case * update import library * set report category Co-authored-by: Yuvraj <yuvraj.yad001@gmail.com> Co-authored-by: Yuvraj <10830562+evalsocket@users.noreply.github.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com>
119 lines
4.5 KiB
Go
119 lines
4.5 KiB
Go
package engine
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
|
"github.com/kyverno/kyverno/pkg/engine/mutate"
|
|
"github.com/kyverno/kyverno/pkg/engine/response"
|
|
"github.com/kyverno/kyverno/pkg/engine/variables"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"sigs.k8s.io/controller-runtime/pkg/log"
|
|
)
|
|
|
|
const (
|
|
// PodControllerCronJob represent CronJob string
|
|
PodControllerCronJob = "CronJob"
|
|
//PodControllers stores the list of Pod-controllers in csv string
|
|
PodControllers = "DaemonSet,Deployment,Job,StatefulSet,CronJob"
|
|
//PodControllersAnnotation defines the annotation key for Pod-Controllers
|
|
PodControllersAnnotation = "pod-policies.kyverno.io/autogen-controllers"
|
|
)
|
|
|
|
// Mutate performs mutation. Overlay first and then mutation patches
|
|
func Mutate(policyContext PolicyContext) (resp response.EngineResponse) {
|
|
startTime := time.Now()
|
|
policy := policyContext.Policy
|
|
patchedResource := policyContext.NewResource
|
|
ctx := policyContext.Context
|
|
|
|
resCache := policyContext.ResourceCache
|
|
jsonContext := policyContext.JSONContext
|
|
logger := log.Log.WithName("EngineMutate").WithValues("policy", policy.Name, "kind", patchedResource.GetKind(),
|
|
"namespace", patchedResource.GetNamespace(), "name", patchedResource.GetName())
|
|
|
|
logger.V(4).Info("start policy processing", "startTime", startTime)
|
|
|
|
startMutateResultResponse(&resp, policy, patchedResource)
|
|
defer endMutateResultResponse(logger, &resp, startTime)
|
|
|
|
if SkipPolicyApplication(policy, patchedResource) {
|
|
logger.V(5).Info("Skip applying policy, Pod has ownerRef set", "policy", policy.GetName())
|
|
resp.PatchedResource = patchedResource
|
|
return
|
|
}
|
|
|
|
for _, rule := range policy.Spec.Rules {
|
|
var ruleResponse response.RuleResponse
|
|
logger := logger.WithValues("rule", rule.Name)
|
|
if !rule.HasMutate() {
|
|
continue
|
|
}
|
|
|
|
// check if the resource satisfies the filter conditions defined in the rule
|
|
//TODO: this needs to be extracted, to filter the resource so that we can avoid passing resources that
|
|
// dont satisfy a policy rule resource description
|
|
excludeResource := []string{}
|
|
if len(policyContext.ExcludeGroupRole) > 0 {
|
|
excludeResource = policyContext.ExcludeGroupRole
|
|
}
|
|
if err := MatchesResourceDescription(patchedResource, rule, policyContext.AdmissionInfo, excludeResource); err != nil {
|
|
logger.V(3).Info("resource not matched", "reason", err.Error())
|
|
continue
|
|
}
|
|
|
|
// add configmap json data to context
|
|
if err := AddResourceToContext(logger, rule.Context, resCache, jsonContext); err != nil {
|
|
logger.V(4).Info("cannot add configmaps to context", "reason", err.Error())
|
|
continue
|
|
}
|
|
|
|
// operate on the copy of the conditions, as we perform variable substitution
|
|
copyConditions := copyConditions(rule.Conditions)
|
|
// evaluate pre-conditions
|
|
// - handle variable substitutions
|
|
if !variables.EvaluateConditions(logger, ctx, copyConditions) {
|
|
logger.V(3).Info("resource fails the preconditions")
|
|
continue
|
|
}
|
|
|
|
mutation := rule.Mutation.DeepCopy()
|
|
|
|
mutateHandler := mutate.CreateMutateHandler(rule.Name, mutation, patchedResource, ctx, logger)
|
|
ruleResponse, patchedResource = mutateHandler.Handle()
|
|
if ruleResponse.Success {
|
|
// - overlay pattern does not match the resource conditions
|
|
if ruleResponse.Patches == nil {
|
|
continue
|
|
}
|
|
logger.V(4).Info("mutate rule applied successfully", "ruleName", rule.Name)
|
|
}
|
|
|
|
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, ruleResponse)
|
|
incrementAppliedRuleCount(&resp)
|
|
}
|
|
|
|
resp.PatchedResource = patchedResource
|
|
return resp
|
|
}
|
|
|
|
func incrementAppliedRuleCount(resp *response.EngineResponse) {
|
|
resp.PolicyResponse.RulesAppliedCount++
|
|
}
|
|
|
|
func startMutateResultResponse(resp *response.EngineResponse, policy kyverno.ClusterPolicy, resource unstructured.Unstructured) {
|
|
// set policy information
|
|
resp.PolicyResponse.Policy = policy.Name
|
|
// resource details
|
|
resp.PolicyResponse.Resource.Name = resource.GetName()
|
|
resp.PolicyResponse.Resource.Namespace = resource.GetNamespace()
|
|
resp.PolicyResponse.Resource.Kind = resource.GetKind()
|
|
resp.PolicyResponse.Resource.APIVersion = resource.GetAPIVersion()
|
|
// TODO(shuting): set response with mutationFailureAction
|
|
}
|
|
|
|
func endMutateResultResponse(logger logr.Logger, resp *response.EngineResponse, startTime time.Time) {
|
|
resp.PolicyResponse.ProcessingTime = time.Since(startTime)
|
|
logger.V(4).Info("finished processing policy", "processingTime", resp.PolicyResponse.ProcessingTime.String(), "mutationRulesApplied", resp.PolicyResponse.RulesAppliedCount)
|
|
}
|