mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
ctr get policy->client notfrom plister(kind empty)
This commit is contained in:
parent
0a1185d1fd
commit
444549d9b7
5 changed files with 110 additions and 37 deletions
|
@ -2,6 +2,7 @@ package controller
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -64,7 +65,11 @@ func (pc *PolicyController) createPolicyHandler(resource interface{}) {
|
|||
func (pc *PolicyController) updatePolicyHandler(oldResource, newResource interface{}) {
|
||||
newPolicy := newResource.(*types.Policy)
|
||||
oldPolicy := oldResource.(*types.Policy)
|
||||
if newPolicy.ResourceVersion == oldPolicy.ResourceVersion {
|
||||
newPolicy.Status = types.Status{}
|
||||
oldPolicy.Status = types.Status{}
|
||||
newPolicy.ResourceVersion = ""
|
||||
oldPolicy.ResourceVersion = ""
|
||||
if reflect.DeepEqual(newPolicy.ResourceVersion, oldPolicy.ResourceVersion) {
|
||||
return
|
||||
}
|
||||
pc.enqueuePolicy(newResource)
|
||||
|
|
|
@ -107,8 +107,8 @@ func (c *Client) getGroupVersionMapper(resource string) schema.GroupVersionResou
|
|||
}
|
||||
|
||||
// GetResource returns the resource in unstructured/json format
|
||||
func (c *Client) GetResource(resource string, namespace string, name string) (*unstructured.Unstructured, error) {
|
||||
return c.getResourceInterface(resource, namespace).Get(name, meta.GetOptions{})
|
||||
func (c *Client) GetResource(resource string, namespace string, name string, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
return c.getResourceInterface(resource, namespace).Get(name, meta.GetOptions{}, subresources...)
|
||||
}
|
||||
|
||||
// ListResource returns the list of resources in unstructured/json format
|
||||
|
|
|
@ -21,7 +21,7 @@ func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersio
|
|||
|
||||
ok := ResourceMeetsDescription(rawResource, rule.ResourceDescription, gvk)
|
||||
if !ok {
|
||||
glog.V(3).Info("Not applicable on specified resource kind%s", gvk.Kind)
|
||||
glog.V(3).Infof("Not applicable on specified resource kind%s", gvk.Kind)
|
||||
continue
|
||||
}
|
||||
// Process Overlay
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package violation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/glog"
|
||||
types "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1"
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/client/listers/policy/v1alpha1"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
event "github.com/nirmata/kyverno/pkg/event"
|
||||
"github.com/nirmata/kyverno/pkg/sharedinformer"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
//Generator to generate policy violation
|
||||
|
@ -25,7 +27,7 @@ type builder struct {
|
|||
type Builder interface {
|
||||
Generator
|
||||
processViolation(info *Info) error
|
||||
isActive(kind string, resource string) (bool, error)
|
||||
isActive(kind string, rname string, rnamespace string) (bool, error)
|
||||
}
|
||||
|
||||
//NewPolicyViolationBuilder returns new violation builder
|
||||
|
@ -49,50 +51,116 @@ func (b *builder) Add(infos ...*Info) error {
|
|||
}
|
||||
|
||||
func (b *builder) processViolation(info *Info) error {
|
||||
policy, err := b.policyLister.Get(info.Policy)
|
||||
currentViolations := []interface{}{}
|
||||
statusMap := map[string]interface{}{}
|
||||
var ok bool
|
||||
//TODO: hack get from client
|
||||
p1, err := b.client.GetResource("policies", "", info.Policy, "status")
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
modifiedPolicy := policy.DeepCopy()
|
||||
modifiedViolations := []types.Violation{}
|
||||
|
||||
// Create new violation
|
||||
newViolation := info.Violation
|
||||
|
||||
for _, violation := range modifiedPolicy.Status.Violations {
|
||||
ok, err := b.isActive(info.Kind, violation.Name)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
continue
|
||||
unstr := p1.UnstructuredContent()
|
||||
// check if "status" field exists
|
||||
status, ok := unstr["status"]
|
||||
if ok {
|
||||
// status is already present then we append violations
|
||||
if statusMap, ok = status.(map[string]interface{}); !ok {
|
||||
return errors.New("Unable to parse status subresource")
|
||||
}
|
||||
violations, ok := statusMap["violations"]
|
||||
if !ok {
|
||||
glog.Info("removed violation")
|
||||
glog.Info("violation not present")
|
||||
}
|
||||
glog.Info(reflect.TypeOf(violations))
|
||||
if currentViolations, ok = violations.([]interface{}); !ok {
|
||||
return errors.New("Unable to parse violations")
|
||||
}
|
||||
}
|
||||
// If violation already exists for this rule, we update the violation
|
||||
//TODO: update violation, instead of re-creating one every time
|
||||
modifiedViolations = append(modifiedViolations, newViolation)
|
||||
|
||||
modifiedPolicy.Status.Violations = modifiedViolations
|
||||
// Violations are part of the status sub resource, so we can use the Update Status api instead of updating the policy object
|
||||
_, err = b.client.UpdateStatusResource("policies", "", modifiedPolicy, false)
|
||||
newViolation := info.Violation
|
||||
for _, violation := range currentViolations {
|
||||
glog.Info(reflect.TypeOf(violation))
|
||||
if v, ok := violation.(map[string]interface{}); ok {
|
||||
if name, ok := v["name"].(string); ok {
|
||||
if namespace, ok := v["namespace"].(string); ok {
|
||||
ok, err := b.isActive(info.Kind, name, namespace)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
continue
|
||||
}
|
||||
if !ok {
|
||||
//TODO remove the violation as it corresponds to resource that does not exist
|
||||
glog.Info("removed violation")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentViolations = append(currentViolations, newViolation)
|
||||
// update violations
|
||||
// set the updated status
|
||||
statusMap["violations"] = currentViolations
|
||||
unstr["status"] = statusMap
|
||||
p1.SetUnstructuredContent(unstr)
|
||||
_, err = b.client.UpdateStatusResource("policies", "", p1, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
// modifiedViolations := []types.Violation{}
|
||||
// modifiedViolations = append(modifiedViolations, types.Violation{Name: "name", Kind: "Deploymeny"})
|
||||
// unstr["status"] = modifiedViolations
|
||||
// p1.SetUnstructuredContent(unstr)
|
||||
// rdata, err := p1.MarshalJSON()
|
||||
// if err != nil {
|
||||
// glog.Info(err)
|
||||
// }
|
||||
// glog.Info(string(rdata))
|
||||
// _, err = b.client.UpdateStatusResource("policies", "", p1, false)
|
||||
// if err != nil {
|
||||
// glog.Info(err)
|
||||
// }
|
||||
|
||||
// p, err := b.policyLister.Get(info.Policy)
|
||||
// if err != nil {
|
||||
// glog.Error(err)
|
||||
// return err
|
||||
// }
|
||||
|
||||
// glog.Info(p.TypeMeta.Kind)
|
||||
// glog.Info(p.Kind)
|
||||
// modifiedPolicy := p.DeepCopy()
|
||||
// glog.Info(modifiedPolicy.Kind)
|
||||
// // Create new violation
|
||||
// newViolation := info.Violation
|
||||
|
||||
// for _, violation := range modifiedPolicy.Status.Violations {
|
||||
// ok, err := b.isActive(info.Kind, violation.Name)
|
||||
// if err != nil {
|
||||
// glog.Error(err)
|
||||
// continue
|
||||
// }
|
||||
// if !ok {
|
||||
// glog.Info("removed violation")
|
||||
// }
|
||||
// }
|
||||
// // If violation already exists for this rule, we update the violation
|
||||
// //TODO: update violation, instead of re-creating one every time
|
||||
// modifiedViolations = append(modifiedViolations, newViolation)
|
||||
// modifiedPolicy.Status.Violations = modifiedViolations
|
||||
// // Violations are part of the status sub resource, so we can use the Update Status api instead of updating the policy object
|
||||
// _, err = b.client.UpdateStatusResource("policies", "", *modifiedPolicy, false)
|
||||
// if err != nil {
|
||||
// glog.Info(err)
|
||||
// return err
|
||||
// }
|
||||
// return nil
|
||||
}
|
||||
|
||||
func (b *builder) isActive(kind string, resource string) (bool, error) {
|
||||
namespace, name, err := cache.SplitMetaNamespaceKey(resource)
|
||||
if err != nil {
|
||||
glog.Errorf("invalid resource key: %s", resource)
|
||||
return false, err
|
||||
}
|
||||
func (b *builder) isActive(kind string, rname string, rnamespace string) (bool, error) {
|
||||
// Generate Merge Patch
|
||||
_, err = b.client.GetResource(kind, namespace, name)
|
||||
_, err := b.client.GetResource(b.client.DiscoveryClient.GetGVRFromKind(kind).Resource, rnamespace, rname)
|
||||
if err != nil {
|
||||
glog.Errorf("unable to get resource %s ", resource)
|
||||
glog.Errorf("unable to get resource %s/%s ", rnamespace, rname)
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
|
@ -118,7 +186,8 @@ func NewViolationFromEvent(e *event.Info, pName string, rKind string, rName stri
|
|||
Kind: rKind,
|
||||
Name: rName,
|
||||
Namespace: rnamespace,
|
||||
Reason: e.Message,
|
||||
Reason: e.Reason,
|
||||
Message: e.Message,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,6 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) *v1be
|
|||
var allPatches []engine.PatchBytes
|
||||
policyInfos := []*info.PolicyInfo{}
|
||||
for _, policy := range policies {
|
||||
|
||||
// check if policy has a rule for the admission request kind
|
||||
if !StringInSlice(request.Kind.Kind, getApplicableKindsForPolicy(policy)) {
|
||||
continue
|
||||
|
|
Loading…
Reference in a new issue