1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

Merge branch 'develop' into lists-validation

This commit is contained in:
Maxim Goncharenko 2019-05-16 21:38:42 +03:00
commit e580c5e0ac
9 changed files with 153 additions and 74 deletions

View file

@ -78,7 +78,7 @@ spec :
data: # data is optional
status:
events:
# log of applied policies. We will need a way to distingush between failed
# log of applied policies. We will need a way to distinguish between failed
# and succeeded operations

12
init.go
View file

@ -17,13 +17,12 @@ func createClientConfig(kubeconfig string) (*rest.Config, error) {
if kubeconfig == "" {
log.Printf("Using in-cluster configuration")
return rest.InClusterConfig()
} else {
}
log.Printf("Using configuration from '%s'", kubeconfig)
return clientcmd.BuildConfigFromFlags("", kubeconfig)
}
}
func initTlsPemPair(certFile, keyFile string, clientConfig *rest.Config, kubeclient *kubeclient.KubeClient) (*tls.TlsPemPair, error) {
func initTLSPemPair(certFile, keyFile string, clientConfig *rest.Config, kubeclient *kubeclient.KubeClient) (*tls.TlsPemPair, error) {
var tlsPair *tls.TlsPemPair
if certFile != "" || keyFile != "" {
tlsPair = tlsPairFromFiles(certFile, keyFile)
@ -32,11 +31,10 @@ func initTlsPemPair(certFile, keyFile string, clientConfig *rest.Config, kubecli
var err error
if tlsPair != nil {
return tlsPair, nil
} else {
}
tlsPair, err = tlsPairFromCluster(clientConfig, kubeclient)
return tlsPair, err
}
}
// Loads PEM private key and TLS certificate from given files
func tlsPairFromFiles(certFile, keyFile string) *tls.TlsPemPair {
@ -66,14 +64,14 @@ func tlsPairFromFiles(certFile, keyFile string) *tls.TlsPemPair {
// Created pair is stored in cluster's secret.
// Returns struct with key/certificate pair.
func tlsPairFromCluster(configuration *rest.Config, client *kubeclient.KubeClient) (*tls.TlsPemPair, error) {
apiServerUrl, err := url.Parse(configuration.Host)
apiServerURL, err := url.Parse(configuration.Host)
if err != nil {
return nil, err
}
certProps := tls.TlsCertificateProps{
Service: config.WebhookServiceName,
Namespace: config.KubePolicyNamespace,
ApiServerHost: apiServerUrl.Hostname(),
ApiServerHost: apiServerURL.Hostname(),
}
tlsPair := client.ReadTlsPair(certProps)

View file

@ -54,7 +54,7 @@ func main() {
log.Fatalf("Error creating mutation webhook: %v\n", err)
}
tlsPair, err := initTlsPemPair(cert, key, clientConfig, kubeclient)
tlsPair, err := initTLSPemPair(cert, key, clientConfig, kubeclient)
if err != nil {
log.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err)
}

View file

@ -0,0 +1,87 @@
package v1alpha1
import (
"testing"
"gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var defaultResourceDescriptionName = "defaultResourceDescription"
var defaultResourceDescription = ResourceDescription{
Kind: "Deployment",
Name: &defaultResourceDescriptionName,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"LabelForSelector": "defaultResourceDescription"},
},
}
func Test_EmptyRule(t *testing.T) {
emptyRule := Rule{
Name: "defaultRule",
ResourceDescription: defaultResourceDescription,
}
err := emptyRule.Validate()
assert.Assert(t, err != nil)
}
func Test_ResourceDescription(t *testing.T) {
err := defaultResourceDescription.Validate()
assert.NilError(t, err)
}
func Test_ResourceDescription_EmptyKind(t *testing.T) {
resourceDescription := ResourceDescription{
Name: &defaultResourceDescriptionName,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"LabelForSelector": "defaultResourceDescription"},
},
}
err := resourceDescription.Validate()
assert.Assert(t, err != nil)
}
func Test_ResourceDescription_EmptyNameAndSelector(t *testing.T) {
resourceDescription := ResourceDescription{
Kind: "Deployment",
}
err := resourceDescription.Validate()
assert.Assert(t, err != nil)
}
func Test_Patch_EmptyPath(t *testing.T) {
patch := Patch{
Operation: "add",
Value: "true",
}
err := patch.Validate()
assert.Assert(t, err != nil)
}
func Test_Patch_EmptyValueWithAdd(t *testing.T) {
patch := Patch{
Path: "/metadata/labels/is-mutated",
Operation: "add",
}
err := patch.Validate()
assert.Assert(t, err != nil)
}
func Test_Patch_UnsupportedOperation(t *testing.T) {
patch := Patch{
Path: "/metadata/labels/is-mutated",
Operation: "overwrite",
Value: "true",
}
err := patch.Validate()
assert.Assert(t, err != nil)
}
func Test_Generation_EmptyCopyFrom(t *testing.T) {
generation := Generation{
Kind: "ConfigMap",
Name: "comfigmapGenerator",
}
err := generation.Validate()
assert.Assert(t, err != nil)
}

View file

@ -3,6 +3,7 @@ package mutation
import (
"encoding/json"
"errors"
"log"
jsonpatch "github.com/evanphx/json-patch"
kubepolicy "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
@ -10,7 +11,7 @@ import (
type PatchBytes []byte
// Returns array from separate patches that can be applied to the document
// 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(patches []kubepolicy.Patch, resource []byte) ([]PatchBytes, error) {
if len(resource) == 0 {
@ -18,7 +19,7 @@ func ProcessPatches(patches []kubepolicy.Patch, resource []byte) ([]PatchBytes,
}
var appliedPatches []PatchBytes
for _, patch := range patches {
for i, patch := range patches {
patchRaw, err := json.Marshal(patch)
if err != nil {
return nil, err
@ -26,7 +27,9 @@ func ProcessPatches(patches []kubepolicy.Patch, resource []byte) ([]PatchBytes,
_, err = applyPatch(resource, patchRaw)
if err != nil {
return nil, err
// TODO: continue on error if one of the patches fails, will add the failure event in such case
log.Printf("Patch failed: patch number = %d, patch Operation = %s, err: %v", i, patch.Operation, err)
continue
}
appliedPatches = append(appliedPatches, patchRaw)
@ -44,7 +47,7 @@ func JoinPatches(patches []PatchBytes) PatchBytes {
result = append(result, []byte("[\n")...)
for index, patch := range patches {
result = append(result, patch...)
if index != (len(patches) - 1) {
if index != len(patches)-1 {
result = append(result, []byte(",\n")...)
}
}

View file

@ -34,14 +34,14 @@ const endpointsDocument string = `{
}`
func TestProcessPatches_EmptyPatches(t *testing.T) {
var empty []types.PolicyPatch
patches, err := ProcessPatches(empty, []byte(endpointsDocument), PatchingSetsDefault)
var empty []types.Patch
patches, err := ProcessPatches(empty, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patches) == 0)
}
func makeAddIsMutatedLabelPatch() types.PolicyPatch {
return types.PolicyPatch{
func makeAddIsMutatedLabelPatch() types.Patch {
return types.Patch{
Path: "/metadata/labels/is-mutated",
Operation: "add",
Value: "true",
@ -49,78 +49,69 @@ func makeAddIsMutatedLabelPatch() types.PolicyPatch {
}
func TestProcessPatches_EmptyDocument(t *testing.T) {
var patches []types.PolicyPatch
var patches []types.Patch
patches = append(patches, makeAddIsMutatedLabelPatch())
patchesBytes, err := ProcessPatches(patches, nil, PatchingSetsDefault)
patchesBytes, err := ProcessPatches(patches, nil)
assert.Assert(t, err != nil)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AllEmpty(t *testing.T) {
patchesBytes, err := ProcessPatches(nil, nil, PatchingSetsDefault)
patchesBytes, err := ProcessPatches(nil, nil)
assert.Assert(t, err != nil)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AddPathDoesntExist_StopOnError(t *testing.T) {
func TestProcessPatches_AddPathDoesntExist(t *testing.T) {
patch := makeAddIsMutatedLabelPatch()
patch.Path = "/metadata/additional/is-mutated"
patches := []types.PolicyPatch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsStopOnError)
assert.Assert(t, err != nil)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AddPathDoesntExist_ContinueOnError(t *testing.T) {
patch := makeAddIsMutatedLabelPatch()
patch.Path = "/metadata/additional/is-mutated"
patches := []types.PolicyPatch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsContinueAlways)
patches := []types.Patch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_RemovePathDoesntExist_StopOnError(t *testing.T) {
patch := types.PolicyPatch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patches := []types.PolicyPatch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsStopOnError)
assert.Assert(t, err != nil)
func TestProcessPatches_RemovePathDoesntExist(t *testing.T) {
patch := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patches := []types.Patch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_EmptyResult(t *testing.T) {
patch1 := types.PolicyPatch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.PolicyPatch{Path: "/spec/labels/label3", Operation: "add", Value: "label3Value"}
patches := []types.PolicyPatch{patch1, patch2}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsContinueAlways)
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"}
patches := []types.Patch{patch1, patch2}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_NotEmptyResult(t *testing.T) {
patch1 := types.PolicyPatch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.PolicyPatch{Path: "/spec/labels/label2", Operation: "remove", Value: "label2Value"}
patch3 := types.PolicyPatch{Path: "/metadata/labels/label3", Operation: "add", Value: "label3Value"}
patches := []types.PolicyPatch{patch1, patch2, patch3}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsContinueAlways)
patch1 := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.Patch{Path: "/spec/labels/label2", Operation: "remove", Value: "label2Value"}
patch3 := types.Patch{Path: "/metadata/labels/label3", Operation: "add", Value: "label3Value"}
patches := []types.Patch{patch1, patch2, patch3}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 1)
assertEqStringAndData(t, `{"path":"/metadata/labels/label3","op":"add","value":"label3Value"}`, patchesBytes[0])
}
func TestProcessPatches_RemovePathDoesntExist_IgnoreRemoveFailures_EmptyResult(t *testing.T) {
patch := types.PolicyPatch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patches := []types.PolicyPatch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsContinueOnRemoveFailure)
func TestProcessPatches_RemovePathDoesntExist_EmptyResult(t *testing.T) {
patch := types.Patch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patches := []types.Patch{patch}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 0)
}
func TestProcessPatches_RemovePathDoesntExist_IgnoreRemoveFailures_NotEmptyResult(t *testing.T) {
patch1 := types.PolicyPatch{Path: "/metadata/labels/is-mutated", Operation: "remove"}
patch2 := types.PolicyPatch{Path: "/metadata/labels/label2", Operation: "add", Value: "label2Value"}
patches := []types.PolicyPatch{patch1, patch2}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument), PatchingSetsContinueOnRemoveFailure)
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"}
patches := []types.Patch{patch1, patch2}
patchesBytes, err := ProcessPatches(patches, []byte(endpointsDocument))
assert.NilError(t, err)
assert.Assert(t, len(patchesBytes) == 1)
assertEqStringAndData(t, `{"path":"/metadata/labels/label2","op":"add","value":"label2Value"}`, patchesBytes[0])

View file

@ -115,7 +115,7 @@ func (c *controller) processNextWorkItem() bool {
}(obj)
if err != nil {
log.Println((err))
log.Println(err)
}
return true
}

View file

@ -10,7 +10,7 @@ func (k MsgKey) String() string {
"Failed to satisfy policy on resource %s.The following rules %s failed to apply. Created Policy Violation",
"Failed to process rule %s of policy %s. Created Policy Violation %s",
"Policy applied successfully on the resource %s",
"Rule %s of Policy %s applied successfull",
"Rule %s of Policy %s applied successful",
"Failed to apply policy, blocked creation of resource %s. The following rules %s failed to apply",
"Failed to apply rule %s of policy %s Blocked update of the resource",
"Failed to apply policy on resource %s.Blocked update of the resource. The following rules %s failed to apply",