mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
Merge branch 'master' into 536_extend_cli
This commit is contained in:
commit
d0da7a8ed4
8 changed files with 77 additions and 43 deletions
|
@ -520,10 +520,10 @@ spec:
|
|||
serviceAccountName: kyverno-service-account
|
||||
initContainers:
|
||||
- name: kyverno-pre
|
||||
image: nirmata/kyvernopre:v1.1.1
|
||||
image: nirmata/kyvernopre:v1.1.2
|
||||
containers:
|
||||
- name: kyverno
|
||||
image: nirmata/kyverno:v1.1.1
|
||||
image: nirmata/kyverno:v1.1.2
|
||||
args:
|
||||
- "--filterK8Resources=[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][*,kyverno,*]"
|
||||
# customize webhook timout
|
||||
|
|
|
@ -374,7 +374,6 @@ func processSubtree(overlay interface{}, path string, op string) ([]byte, error)
|
|||
// check the patch
|
||||
_, err := jsonpatch.DecodePatch([]byte("[" + patchStr + "]"))
|
||||
if err != nil {
|
||||
glog.V(3).Info(err)
|
||||
return nil, fmt.Errorf("Failed to make '%s' patch from an overlay '%s' for path %s, err: %v", op, value, path, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/response"
|
||||
"github.com/nirmata/kyverno/pkg/engine/utils"
|
||||
"github.com/nirmata/kyverno/pkg/engine/variables"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -28,22 +29,10 @@ func Mutate(policyContext PolicyContext) (resp response.EngineResponse) {
|
|||
resource := policyContext.NewResource
|
||||
ctx := policyContext.Context
|
||||
|
||||
// policy information
|
||||
func() {
|
||||
// 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()
|
||||
}()
|
||||
startMutateResultResponse(&resp, policy, resource)
|
||||
glog.V(4).Infof("started applying mutation rules of policy %q (%v)", policy.Name, startTime)
|
||||
defer func() {
|
||||
resp.PolicyResponse.ProcessingTime = time.Since(startTime)
|
||||
glog.V(4).Infof("finished applying mutation rules policy %v (%v)", policy.Name, resp.PolicyResponse.ProcessingTime)
|
||||
glog.V(4).Infof("Mutation Rules appplied count %v for policy %q", resp.PolicyResponse.RulesAppliedCount, policy.Name)
|
||||
}()
|
||||
defer endMutateResultResponse(&resp, startTime)
|
||||
|
||||
incrementAppliedRuleCount := func() {
|
||||
// rules applied succesfully count
|
||||
resp.PolicyResponse.RulesAppliedCount++
|
||||
|
@ -146,6 +135,23 @@ func Mutate(policyContext PolicyContext) (resp response.EngineResponse) {
|
|||
return resp
|
||||
}
|
||||
|
||||
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(resp *response.EngineResponse, startTime time.Time) {
|
||||
resp.PolicyResponse.ProcessingTime = time.Since(startTime)
|
||||
glog.V(4).Infof("finished applying mutation rules policy %v (%v)", resp.PolicyResponse.Policy, resp.PolicyResponse.ProcessingTime)
|
||||
glog.V(4).Infof("Mutation Rules appplied count %v for policy %q", resp.PolicyResponse.RulesAppliedCount, resp.PolicyResponse.Policy)
|
||||
}
|
||||
|
||||
// podTemplateRule mutate pod template with annotation
|
||||
// pod-policies.kyverno.io/autogen-applied=true
|
||||
var podTemplateRule = kyverno.Rule{
|
||||
|
|
|
@ -74,7 +74,6 @@ func startResultResponse(resp *response.EngineResponse, policy kyverno.ClusterPo
|
|||
resp.PolicyResponse.Resource.Kind = newR.GetKind()
|
||||
resp.PolicyResponse.Resource.APIVersion = newR.GetAPIVersion()
|
||||
resp.PolicyResponse.ValidationFailureAction = policy.Spec.ValidationFailureAction
|
||||
|
||||
}
|
||||
|
||||
func endResultResponse(resp *response.EngineResponse, startTime time.Time) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// isResponseSuccesful return true if all responses are successful
|
||||
func isResponseSuccesful(engineReponses []response.EngineResponse) bool {
|
||||
for _, er := range engineReponses {
|
||||
if !er.IsSuccesful() {
|
||||
|
@ -35,6 +36,26 @@ func toBlockResource(engineReponses []response.EngineResponse) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// getEnforceFailureErrorMsg gets the error messages for failed enforce policy
|
||||
func getEnforceFailureErrorMsg(engineReponses []response.EngineResponse) string {
|
||||
var str []string
|
||||
var resourceInfo string
|
||||
|
||||
for _, er := range engineReponses {
|
||||
if !er.IsSuccesful() && er.PolicyResponse.ValidationFailureAction == Enforce {
|
||||
resourceInfo = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
|
||||
str = append(str, fmt.Sprintf("failed policy %s:", er.PolicyResponse.Policy))
|
||||
for _, rule := range er.PolicyResponse.Rules {
|
||||
if !rule.Success {
|
||||
str = append(str, rule.ToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("Resource %s %s", resourceInfo, strings.Join(str, ";"))
|
||||
}
|
||||
|
||||
// getErrorMsg gets all failed engine response message
|
||||
func getErrorMsg(engineReponses []response.EngineResponse) string {
|
||||
var str []string
|
||||
var resourceInfo string
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package webhooks
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/nirmata/kyverno/pkg/engine"
|
||||
|
@ -15,7 +17,8 @@ import (
|
|||
)
|
||||
|
||||
// HandleMutation handles mutating webhook admission request
|
||||
func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resource unstructured.Unstructured, policies []kyverno.ClusterPolicy, roles, clusterRoles []string) (bool, []byte, string) {
|
||||
// return value: generated patches
|
||||
func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resource unstructured.Unstructured, policies []kyverno.ClusterPolicy, roles, clusterRoles []string) []byte {
|
||||
glog.V(4).Infof("Receive request in mutating webhook: Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s",
|
||||
request.Kind.Kind, request.Namespace, request.Name, request.UID, request.Operation)
|
||||
|
||||
|
@ -79,7 +82,6 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
|||
resource.GetKind(), resource.GetNamespace(), resource.GetName(), request.UID, request.Operation)
|
||||
|
||||
policyContext.Policy = policy
|
||||
// TODO: this can be
|
||||
engineResponse := engine.Mutate(policyContext)
|
||||
engineResponses = append(engineResponses, engineResponse)
|
||||
// Gather policy application statistics
|
||||
|
@ -100,7 +102,11 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
|||
patches = append(patches, annPatches)
|
||||
}
|
||||
|
||||
// generate violation when referenced path does not exist
|
||||
// report time
|
||||
reportTime := time.Now()
|
||||
|
||||
// AUDIT
|
||||
// generate violation when response fails
|
||||
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
|
||||
ws.pvGenerator.Add(pvInfos...)
|
||||
|
||||
|
@ -108,13 +114,24 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
|||
events := generateEvents(engineResponses, (request.Operation == v1beta1.Update))
|
||||
ws.eventGen.Add(events...)
|
||||
|
||||
if isResponseSuccesful(engineResponses) {
|
||||
sendStat(false)
|
||||
patch := engineutils.JoinPatches(patches)
|
||||
return true, patch, ""
|
||||
}
|
||||
sendStat(false)
|
||||
|
||||
sendStat(true)
|
||||
glog.Errorf("Failed to mutate the resource, %s\n", getErrorMsg(engineResponses))
|
||||
return false, nil, getErrorMsg(engineResponses)
|
||||
// debug info
|
||||
func() {
|
||||
if len(patches) != 0 {
|
||||
glog.V(4).Infof("Patches generated for %s/%s/%s, operation=%v:\n %v",
|
||||
resource.GetKind(), resource.GetNamespace(), resource.GetName(), request.Operation, string(engineutils.JoinPatches(patches)))
|
||||
}
|
||||
|
||||
// if any of the policies fails, print out the error
|
||||
if !isResponseSuccesful(engineResponses) {
|
||||
glog.Errorf("Failed to mutate the resource, report as violation: %s\n", getErrorMsg(engineResponses))
|
||||
}
|
||||
}()
|
||||
|
||||
// report time end
|
||||
glog.V(4).Infof("report: %v %s/%s/%s", time.Since(reportTime), resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
|
||||
// patches holds all the successful patches, if no patch is created, it returns nil
|
||||
return engineutils.JoinPatches(patches)
|
||||
}
|
||||
|
|
|
@ -235,23 +235,15 @@ func (ws *WebhookServer) handleAdmissionRequest(request *v1beta1.AdmissionReques
|
|||
}
|
||||
|
||||
// MUTATION
|
||||
ok, patches, msg := ws.HandleMutation(request, resource, policies, roles, clusterRoles)
|
||||
if !ok {
|
||||
glog.V(4).Infof("Deny admission request: %v/%s/%s", request.Kind, request.Namespace, request.Name)
|
||||
return &v1beta1.AdmissionResponse{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Status: "Failure",
|
||||
Message: msg,
|
||||
},
|
||||
}
|
||||
}
|
||||
// mutation failure should not block the resource creation
|
||||
// any mutation failure is reported as the violation
|
||||
patches := ws.HandleMutation(request, resource, policies, roles, clusterRoles)
|
||||
|
||||
// patch the resource with patches before handling validation rules
|
||||
patchedResource := processResourceWithPatches(patches, request.Object.Raw)
|
||||
|
||||
// VALIDATION
|
||||
ok, msg = ws.HandleValidation(request, policies, patchedResource, roles, clusterRoles)
|
||||
ok, msg := ws.HandleValidation(request, policies, patchedResource, roles, clusterRoles)
|
||||
if !ok {
|
||||
glog.V(4).Infof("Deny admission request: %v/%s/%s", request.Kind, request.Namespace, request.Name)
|
||||
return &v1beta1.AdmissionResponse{
|
||||
|
|
|
@ -107,7 +107,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, pol
|
|||
if blocked {
|
||||
glog.V(4).Infof("resource %s/%s/%s is blocked\n", newR.GetKind(), newR.GetNamespace(), newR.GetName())
|
||||
sendStat(true)
|
||||
return false, getErrorMsg(engineResponses)
|
||||
return false, getEnforceFailureErrorMsg(engineResponses)
|
||||
}
|
||||
|
||||
// ADD POLICY VIOLATIONS
|
||||
|
|
Loading…
Reference in a new issue