mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 10:28:36 +00:00
combine policy engine returns into single struct
This commit is contained in:
parent
e87c72291f
commit
6b1b6dddfa
9 changed files with 63 additions and 48 deletions
|
@ -1,6 +1,8 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/golang/glog"
|
||||
types "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1"
|
||||
|
@ -45,11 +47,13 @@ func applyPolicy(client *client.Client, policy *types.Policy, res resourceInfo)
|
|||
return nil, err
|
||||
}
|
||||
// Validation
|
||||
vruleInfos, err := Validate(*policy, rawResource, *res.Gvk)
|
||||
policyInfo.AddRuleInfos(vruleInfos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
response := Validate(*policy, rawResource, *res.Gvk)
|
||||
if response != nil {
|
||||
policyInfo.AddRuleInfos(response.RuleInfos)
|
||||
} else {
|
||||
return nil, errors.New("Failed to process validate rule, error parsing rawResource")
|
||||
}
|
||||
|
||||
if res.Gvk.Kind == "Namespace" {
|
||||
|
||||
// Generation
|
||||
|
@ -61,7 +65,10 @@ func applyPolicy(client *client.Client, policy *types.Policy, res resourceInfo)
|
|||
}
|
||||
|
||||
func mutation(p *types.Policy, rawResource []byte, gvk *metav1.GroupVersionKind) ([]*info.RuleInfo, error) {
|
||||
patches, _, ruleInfos := Mutate(*p, rawResource, *gvk)
|
||||
response := Mutate(*p, rawResource, *gvk)
|
||||
patches := response.Patches
|
||||
ruleInfos := response.RuleInfos
|
||||
|
||||
if len(ruleInfos) == 0 {
|
||||
// no rules were processed
|
||||
return nil, nil
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// Mutate performs mutation. Overlay first and then mutation patches
|
||||
func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) ([][]byte, []byte, []*info.RuleInfo) {
|
||||
func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) *EngineResponse {
|
||||
var allPatches, rulePatches [][]byte
|
||||
var err error
|
||||
var errs []error
|
||||
|
@ -69,5 +69,9 @@ func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersio
|
|||
ris = append(ris, ri)
|
||||
}
|
||||
|
||||
return allPatches, patchedDocument, ris
|
||||
return &EngineResponse{
|
||||
Patches: allPatches,
|
||||
PatchedDocument: patchedDocument,
|
||||
RuleInfos: ris,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
types "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1"
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"github.com/nirmata/kyverno/pkg/info"
|
||||
"github.com/nirmata/kyverno/pkg/utils"
|
||||
v1helper "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -20,6 +21,12 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type EngineResponse struct {
|
||||
Patches [][]byte
|
||||
PatchedDocument []byte
|
||||
RuleInfos []*info.RuleInfo
|
||||
}
|
||||
|
||||
//ListResourcesThatApplyToPolicy returns list of resources that are filtered by policy rules
|
||||
func ListResourcesThatApplyToPolicy(client *client.Client, policy *types.Policy, filterK8Resources []utils.K8Resource) map[string]resourceInfo {
|
||||
// key uid
|
||||
|
|
|
@ -17,13 +17,13 @@ import (
|
|||
|
||||
// Validate handles validating admission request
|
||||
// Checks the target resources for rules defined in the policy
|
||||
func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) ([]*info.RuleInfo, error) {
|
||||
func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) *EngineResponse {
|
||||
var resource interface{}
|
||||
ris := []*info.RuleInfo{}
|
||||
|
||||
err := json.Unmarshal(rawResource, &resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err := json.Unmarshal(rawResource, &resource); err != nil {
|
||||
glog.Errorf("Failed to parse rawResource err: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
|
@ -49,7 +49,9 @@ func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVers
|
|||
ris = append(ris, ri)
|
||||
}
|
||||
|
||||
return ris, nil
|
||||
return &EngineResponse{
|
||||
RuleInfos: ris,
|
||||
}
|
||||
}
|
||||
|
||||
// validateResourceWithPattern is a start of element-by-element validation process
|
||||
|
|
|
@ -1573,8 +1573,8 @@ func TestValidate_ServiceTest(t *testing.T) {
|
|||
gvk := metav1.GroupVersionKind{
|
||||
Kind: "Service",
|
||||
}
|
||||
_, err := Validate(policy, rawResource, gvk)
|
||||
assert.Assert(t, err == nil)
|
||||
res := Validate(policy, rawResource, gvk)
|
||||
assert.Assert(t, res != nil)
|
||||
}
|
||||
|
||||
func TestValidate_MapHasFloats(t *testing.T) {
|
||||
|
@ -1672,6 +1672,6 @@ func TestValidate_MapHasFloats(t *testing.T) {
|
|||
Kind: "Deployment",
|
||||
}
|
||||
|
||||
_, err := Validate(policy, rawResource, gvk)
|
||||
assert.NilError(t, err)
|
||||
res := Validate(policy, rawResource, gvk)
|
||||
assert.Assert(t, res != nil)
|
||||
}
|
||||
|
|
|
@ -9,14 +9,13 @@ import (
|
|||
)
|
||||
|
||||
// HandleMutation handles mutating webhook admission request
|
||||
func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool, [][]byte, []byte) {
|
||||
var allPatches, policyPatches [][]byte
|
||||
func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool, *engine.EngineResponse) {
|
||||
var allPatches [][]byte
|
||||
policyInfos := []*info.PolicyInfo{}
|
||||
var ruleInfos []*info.RuleInfo
|
||||
patchedDocument := request.Object.Raw
|
||||
engineResponse := &engine.EngineResponse{PatchedDocument: request.Object.Raw}
|
||||
|
||||
if request.Operation == v1beta1.Delete {
|
||||
return true, nil, patchedDocument
|
||||
return true, engineResponse
|
||||
}
|
||||
|
||||
glog.V(4).Infof("Receive request in mutating webhook: Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s",
|
||||
|
@ -27,7 +26,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool
|
|||
// Unable to connect to policy Lister to access policies
|
||||
glog.Errorln("Unable to connect to policy controller to access policies. Mutation Rules are NOT being applied")
|
||||
glog.Warning(err)
|
||||
return true, nil, patchedDocument
|
||||
return true, engineResponse
|
||||
}
|
||||
|
||||
rname := engine.ParseNameFromObject(request.Object.Raw)
|
||||
|
@ -59,13 +58,12 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool
|
|||
|
||||
glog.Infof("Applying policy %s with %d rules\n", policy.ObjectMeta.Name, len(policy.Spec.Rules))
|
||||
|
||||
policyPatches, patchedDocument, ruleInfos = engine.Mutate(*policy, patchedDocument, request.Kind)
|
||||
|
||||
policyInfo.AddRuleInfos(ruleInfos)
|
||||
engineResponse = engine.Mutate(*policy, engineResponse.PatchedDocument, request.Kind)
|
||||
policyInfo.AddRuleInfos(engineResponse.RuleInfos)
|
||||
|
||||
if !policyInfo.IsSuccessful() {
|
||||
glog.Infof("Failed to apply policy %s on resource %s/%s", policy.Name, rname, rns)
|
||||
for _, r := range ruleInfos {
|
||||
for _, r := range engineResponse.RuleInfos {
|
||||
glog.Warningf("%s: %s\n", r.Name, r.Msgs)
|
||||
}
|
||||
} else {
|
||||
|
@ -74,7 +72,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool
|
|||
if err != nil {
|
||||
glog.Info(err)
|
||||
}
|
||||
allPatches = append(allPatches, policyPatches...)
|
||||
allPatches = append(allPatches, engineResponse.Patches...)
|
||||
glog.Infof("Mutation from policy %s has applied succesfully to %s %s/%s", policy.Name, request.Kind.Kind, rns, rname)
|
||||
}
|
||||
policyInfos = append(policyInfos, policyInfo)
|
||||
|
@ -93,9 +91,10 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool
|
|||
|
||||
ok, msg := isAdmSuccesful(policyInfos)
|
||||
if ok {
|
||||
return true, allPatches, patchedDocument
|
||||
engineResponse.Patches = allPatches
|
||||
return true, engineResponse
|
||||
}
|
||||
|
||||
glog.Errorf("Failed to mutate the resource: %s\n", msg)
|
||||
return false, nil, patchedDocument
|
||||
return false, engineResponse
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ func (ws *WebhookServer) serve(w http.ResponseWriter, r *http.Request) {
|
|||
func (ws *WebhookServer) HandleAdmissionRequest(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
||||
var response *v1beta1.AdmissionResponse
|
||||
|
||||
allowed, allPatches, patchedDocument := ws.HandleMutation(request)
|
||||
allowed, engineResponse := ws.HandleMutation(request)
|
||||
if !allowed {
|
||||
// TODO: add failure message to response
|
||||
return &v1beta1.AdmissionResponse{
|
||||
|
@ -148,10 +148,10 @@ func (ws *WebhookServer) HandleAdmissionRequest(request *v1beta1.AdmissionReques
|
|||
}
|
||||
}
|
||||
|
||||
response = ws.HandleValidation(request, patchedDocument)
|
||||
if response.Allowed && len(allPatches) > 0 {
|
||||
response = ws.HandleValidation(request, engineResponse.PatchedDocument)
|
||||
if response.Allowed && len(engineResponse.Patches) > 0 {
|
||||
patchType := v1beta1.PatchTypeJSONPatch
|
||||
response.Patch = engine.JoinPatches(allPatches)
|
||||
response.Patch = engine.JoinPatches(engineResponse.Patches)
|
||||
response.PatchType = &patchType
|
||||
}
|
||||
|
||||
|
|
|
@ -57,19 +57,16 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, raw
|
|||
request.Kind.Kind, rns, rname, request.UID, request.Operation)
|
||||
|
||||
glog.Infof("Validating resource %s/%s/%s with policy %s with %d rules", rkind, rns, rname, policy.ObjectMeta.Name, len(policy.Spec.Rules))
|
||||
ruleInfos, err := engine.Validate(*policy, rawResource, request.Kind)
|
||||
if err != nil {
|
||||
// This is not policy error
|
||||
// but if unable to parse request raw resource
|
||||
// TODO : create event ? dont think so
|
||||
glog.Error(err)
|
||||
engineResponse := engine.Validate(*policy, rawResource, request.Kind)
|
||||
if engineResponse == nil {
|
||||
glog.Errorln("Failed to process validate rule, error parsing rawResource")
|
||||
continue
|
||||
}
|
||||
policyInfo.AddRuleInfos(ruleInfos)
|
||||
policyInfo.AddRuleInfos(engineResponse.RuleInfos)
|
||||
|
||||
if !policyInfo.IsSuccessful() {
|
||||
glog.Infof("Failed to apply policy %s on resource %s/%s", policy.Name, rname, rns)
|
||||
for _, r := range ruleInfos {
|
||||
for _, r := range engineResponse.RuleInfos {
|
||||
glog.Warningf("%s: %s\n", r.Name, r.Msgs)
|
||||
}
|
||||
} else {
|
||||
|
@ -79,7 +76,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, raw
|
|||
glog.Info(err)
|
||||
}
|
||||
|
||||
if len(ruleInfos) > 0 {
|
||||
if len(engineResponse.RuleInfos) > 0 {
|
||||
glog.Infof("Validation from policy %s has applied succesfully to %s %s/%s", policy.Name, request.Kind.Kind, rname, rns)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,13 @@ func (ws *WebhookServer) manageWebhookConfigurations(policy v1alpha1.Policy, op
|
|||
}
|
||||
|
||||
func (ws *WebhookServer) registerWebhookConfigurations(policy v1alpha1.Policy) error {
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
if rule.Mutation != nil && !ws.webhookRegistrationClient.MutationRegistered.IsSet() {
|
||||
if err := ws.webhookRegistrationClient.RegisterMutatingWebhook(); err != nil {
|
||||
return err
|
||||
}
|
||||
glog.Infof("Mutating webhook registered")
|
||||
if !ws.webhookRegistrationClient.MutationRegistered.IsSet() {
|
||||
if err := ws.webhookRegistrationClient.RegisterMutatingWebhook(); err != nil {
|
||||
return err
|
||||
}
|
||||
glog.Infof("Mutating webhook registered")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue