1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 10:28:36 +00:00
This commit is contained in:
shivkumar dudhani 2019-08-09 11:08:02 -07:00
parent a813b84c24
commit a30ad6bab2
7 changed files with 53 additions and 24 deletions

View file

@ -14,7 +14,6 @@ import (
"github.com/nirmata/kyverno/pkg/policyviolation"
"github.com/nirmata/kyverno/pkg/sharedinformer"
"github.com/nirmata/kyverno/pkg/utils"
"github.com/nirmata/kyverno/pkg/violation"
"github.com/nirmata/kyverno/pkg/webhooks"
"k8s.io/sample-controller/pkg/signals"
)
@ -64,7 +63,7 @@ func main() {
}
kubeInformer := utils.NewKubeInformerFactory(clientConfig)
eventController := event.NewEventController(client, policyInformerFactory)
violationBuilder := violation.NewPolicyViolationBuilder(client, policyInformerFactory, eventController)
// violationBuilder := violation.NewPolicyViolationBuilder(client, policyInformerFactory, eventController)
annotationsController := annotations.NewAnnotationControler(client)
// policyController := controller.NewPolicyController(
// client,
@ -79,7 +78,7 @@ func main() {
if err != nil {
glog.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err)
}
server, err := webhooks.NewWebhookServer(client, tlsPair, policyInformerFactory, eventController, violationBuilder, annotationsController, filterK8Resources)
server, err := webhooks.NewWebhookServer(client, tlsPair, policyInformerFactory, eventController, nil, annotationsController, filterK8Resources)
if err != nil {
glog.Fatalf("Unable to create webhook server: %v\n", err)
}

View file

@ -5,10 +5,13 @@ import (
kubepolicy "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1"
"github.com/nirmata/kyverno/pkg/info"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// Mutate performs mutation. Overlay first and then mutation patches
func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) ([][]byte, []*info.RuleInfo) {
//
var allPatches [][]byte
patchedDocument := rawResource
ris := []*info.RuleInfo{}
@ -17,16 +20,22 @@ func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersio
if rule.Mutation == nil {
continue
}
ri := info.NewRuleInfo(rule.Name, info.Mutation)
// 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 statisfy a policy rule resource description
ok := ResourceMeetsDescription(rawResource, rule.MatchResources.ResourceDescription, rule.ExcludeResources.ResourceDescription, gvk)
if !ok {
glog.V(3).Infof("Not applicable on specified resource kind%s", gvk.Kind)
name := ParseNameFromObject(rawResource)
namespace := ParseNamespaceFromObject(rawResource)
glog.V(3).Infof("resource %s/%s does not satisfy the resource description for the rule ", namespace, name)
continue
}
ri := info.NewRuleInfo(rule.Name, info.Mutation)
// Process Overlay
if rule.Mutation.Overlay != nil {
overlayPatches, err := ProcessOverlay(rule, rawResource, gvk)
overlayPatches, err := processOverlay(rule, rawResource, gvk)
if err == nil {
if len(overlayPatches) == 0 {
// if array elements dont match then we skip(nil patch, no error)
@ -34,28 +43,32 @@ func Mutate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersio
// policy is not applicable
continue
}
ri.Addf("Rule %s: Overlay succesfully applied.", rule.Name)
// merge the json patches
glog.V(4).Infof("overlay applied succesfully on resource")
ri.Add("Overlay succesfully applied")
patch := JoinPatches(overlayPatches)
allPatches = append(allPatches, overlayPatches...)
// update rule information
// strip slashes from string
ri.Changes = string(patch)
allPatches = append(allPatches, overlayPatches...)
} else {
glog.V(4).Infof("failed to apply overlay: %v", err)
ri.Fail()
ri.Addf("overlay application has failed, err %v.", err)
ri.Addf("failed to apply overlay: %v", err)
}
}
// Process Patches
if len(rule.Mutation.Patches) != 0 {
rulePatches, errs := ProcessPatches(rule, patchedDocument)
rulePatches, errs := processPatches(rule, patchedDocument)
if len(errs) > 0 {
ri.Fail()
for _, err := range errs {
glog.V(4).Infof("failed to apply patches: %v", err)
ri.Addf("patches application has failed, err %v.", err)
}
} else {
ri.Addf("Rule %s: Patches succesfully applied.", rule.Name)
glog.V(4).Infof("patches applied succesfully on resource")
ri.Addf("Patches succesfully applied.")
allPatches = append(allPatches, rulePatches...)
}
}

View file

@ -17,7 +17,7 @@ import (
// ProcessOverlay handles validating admission request
// Checks the target resources for rules defined in the policy
func ProcessOverlay(rule kubepolicy.Rule, rawResource []byte, gvk metav1.GroupVersionKind) ([][]byte, error) {
func processOverlay(rule kubepolicy.Rule, rawResource []byte, gvk metav1.GroupVersionKind) ([][]byte, error) {
var resource interface{}
if err := json.Unmarshal(rawResource, &resource); err != nil {

View file

@ -12,7 +12,7 @@ import (
// ProcessPatches Returns array from separate patches that can be applied to the document
// Returns error ONLY in case when creation of resource should be denied.
func ProcessPatches(rule kubepolicy.Rule, resource []byte) (allPatches [][]byte, errs []error) {
func processPatches(rule kubepolicy.Rule, resource []byte) (allPatches [][]byte, errs []error) {
if len(resource) == 0 {
errs = append(errs, errors.New("Source document for patching is empty"))
return nil, errs

View file

@ -35,7 +35,7 @@ const endpointsDocument string = `{
func TestProcessPatches_EmptyPatches(t *testing.T) {
var emptyRule = types.Rule{}
patches, err := ProcessPatches(emptyRule, []byte(endpointsDocument))
patches, err := processPatches(emptyRule, []byte(endpointsDocument))
assert.Check(t, len(err) == 1)
assert.Assert(t, len(patches) == 0)
}
@ -64,14 +64,14 @@ func makeRuleWithPatches(patches []types.Patch) types.Rule {
func TestProcessPatches_EmptyDocument(t *testing.T) {
rule := makeRuleWithPatch(makeAddIsMutatedLabelPatch())
patchesBytes, err := ProcessPatches(rule, nil)
patchesBytes, err := processPatches(rule, nil)
assert.Assert(t, err != nil)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AllEmpty(t *testing.T) {
emptyRule := types.Rule{}
patchesBytes, err := ProcessPatches(emptyRule, nil)
patchesBytes, err := processPatches(emptyRule, nil)
assert.Check(t, len(err) == 1)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -80,7 +80,7 @@ func TestProcessPatches_AddPathDoesntExist(t *testing.T) {
patch := makeAddIsMutatedLabelPatch()
patch.Path = "/metadata/additional/is-mutated"
rule := makeRuleWithPatch(patch)
patchesBytes, err := ProcessPatches(rule, []byte(endpointsDocument))
patchesBytes, err := processPatches(rule, []byte(endpointsDocument))
assert.Check(t, len(err) == 1)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -88,7 +88,7 @@ func TestProcessPatches_AddPathDoesntExist(t *testing.T) {
func TestProcessPatches_RemovePathDoesntExist(t *testing.T) {
patch := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
rule := makeRuleWithPatch(patch)
patchesBytes, err := ProcessPatches(rule, []byte(endpointsDocument))
patchesBytes, err := processPatches(rule, []byte(endpointsDocument))
assert.Check(t, len(err) == 0)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -97,7 +97,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_EmptyResult(t *testing.T) {
patch1 := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.Patch{Path: "/spec/labels/label3", Operation: "add", Value: "label3Value"}
rule := makeRuleWithPatches([]types.Patch{patch1, patch2})
patchesBytes, err := ProcessPatches(rule, []byte(endpointsDocument))
patchesBytes, err := processPatches(rule, []byte(endpointsDocument))
assert.Check(t, len(err) == 1)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -107,7 +107,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_NotEmptyResul
patch2 := types.Patch{Path: "/spec/labels/label2", Operation: "remove", Value: "label2Value"}
patch3 := types.Patch{Path: "/metadata/labels/label3", Operation: "add", Value: "label3Value"}
rule := makeRuleWithPatches([]types.Patch{patch1, patch2, patch3})
patchesBytes, err := ProcessPatches(rule, []byte(endpointsDocument))
patchesBytes, err := processPatches(rule, []byte(endpointsDocument))
assert.Check(t, len(err) == 0)
assert.Assert(t, len(patchesBytes) != 0)
assertEqStringAndData(t, `{"path":"/metadata/labels/label3","op":"add","value":"label3Value"}`, patchesBytes[0])
@ -116,7 +116,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_NotEmptyResul
func TestProcessPatches_RemovePathDoesntExist_EmptyResult(t *testing.T) {
patch := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
rule := makeRuleWithPatch(patch)
patchesBytes, err := ProcessPatches(rule, []byte(endpointsDocument))
patchesBytes, err := processPatches(rule, []byte(endpointsDocument))
assert.Check(t, len(err) == 0)
assert.Assert(t, len(patchesBytes) == 0)
}
@ -125,7 +125,7 @@ func TestProcessPatches_RemovePathDoesntExist_NotEmptyResult(t *testing.T) {
patch1 := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.Patch{Path: "/metadata/labels/label2", Operation: "add", Value: "label2Value"}
rule := makeRuleWithPatches([]types.Patch{patch1, patch2})
patchesBytes, err := ProcessPatches(rule, []byte(endpointsDocument))
patchesBytes, err := processPatches(rule, []byte(endpointsDocument))
assert.Check(t, len(err) == 0)
assert.Assert(t, len(patchesBytes) == 1)
assertEqStringAndData(t, `{"path":"/metadata/labels/label2","op":"add","value":"label2Value"}`, patchesBytes[0])

View file

@ -114,9 +114,9 @@ func (ri RuleType) String() string {
//RuleInfo defines rule struct
type RuleInfo struct {
Name string
RuleType RuleType
Msgs []string
Changes string // this will store the mutation patch being applied by the rule
RuleType RuleType
success bool
}

View file

@ -0,0 +1,17 @@
package policyviolation
import (
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
)
//BuildPolicyViolation returns an value of type PolicyViolation
func BuildPolicyViolation(policy string, resource kyverno.ResourceSpec, fRules []kyverno.ViolatedRule) kyverno.PolicyViolation {
pv := kyverno.PolicyViolation{
Spec: kyverno.PolicyViolationSpec{
Policy: policy,
ResourceSpec: resource,
ViolatedRules: fRules,
},
}
return pv
}