mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 10:28:36 +00:00
Merge commit '2192703df1bb26cb8b30a1aece6f9afeed09b214' into 254_dynamic_webhook_configurations
# Conflicts: # pkg/engine/generation.go # pkg/engine/overlay.go # pkg/engine/utils.go # pkg/engine/utils_test.go # pkg/gencontroller/controller.go # pkg/gencontroller/generation.go # pkg/webhooks/mutation.go # pkg/webhooks/server.go
This commit is contained in:
commit
a83e5c1d05
55 changed files with 1190 additions and 1706 deletions
|
@ -54,8 +54,10 @@ spec:
|
|||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
namespaces:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchLabels:
|
||||
|
@ -92,8 +94,10 @@ spec:
|
|||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
namespaces:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchLabels:
|
||||
|
|
|
@ -54,8 +54,10 @@ spec:
|
|||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
namespaces:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchLabels:
|
||||
|
@ -92,8 +94,10 @@ spec:
|
|||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
namespaces:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchLabels:
|
||||
|
|
29
main.go
29
main.go
|
@ -2,16 +2,20 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
clientNew "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions"
|
||||
"github.com/nirmata/kyverno/pkg/config"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
event "github.com/nirmata/kyverno/pkg/event"
|
||||
"github.com/nirmata/kyverno/pkg/namespace"
|
||||
"github.com/nirmata/kyverno/pkg/policy"
|
||||
"github.com/nirmata/kyverno/pkg/policyviolation"
|
||||
"github.com/nirmata/kyverno/pkg/utils"
|
||||
"github.com/nirmata/kyverno/pkg/webhooks"
|
||||
kubeinformers "k8s.io/client-go/informers"
|
||||
"k8s.io/sample-controller/pkg/signals"
|
||||
)
|
||||
|
||||
|
@ -39,7 +43,7 @@ func main() {
|
|||
// access CRD resources
|
||||
// - Policy
|
||||
// - PolicyViolation
|
||||
pclient, err := clientNew.NewForConfig(clientConfig)
|
||||
pclient, err := kyvernoclient.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
glog.Fatalf("Error creating client: %v\n", err)
|
||||
}
|
||||
|
@ -54,8 +58,8 @@ func main() {
|
|||
// watches CRD resources:
|
||||
// - Policy
|
||||
// - PolicyVolation
|
||||
// - cache resync time: 30 seconds
|
||||
pInformer := kyvernoinformer.NewSharedInformerFactoryWithOptions(pclient, 30)
|
||||
// - cache resync time: 10 seconds
|
||||
pInformer := kyvernoinformer.NewSharedInformerFactoryWithOptions(pclient, 10*time.Second)
|
||||
// EVENT GENERATOR
|
||||
// - generate event with retry
|
||||
egen := event.NewEventGenerator(client, pInformer.Kyverno().V1alpha1().Policies())
|
||||
|
@ -77,6 +81,19 @@ func main() {
|
|||
glog.Fatalf("error creating policy violation controller: %v\n", err)
|
||||
}
|
||||
|
||||
// NAMESPACE INFORMER
|
||||
// watches namespace resource
|
||||
// - cache resync time: 10 seconds
|
||||
kubeClient, err := utils.NewKubeClient(clientConfig)
|
||||
if err != nil {
|
||||
glog.Fatalf("Error creating kubernetes client: %v\n", err)
|
||||
}
|
||||
kubeInformer := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 10*time.Second)
|
||||
|
||||
// GENERATE CONTROLLER
|
||||
// - watches for Namespace resource and generates resource based on the policy generate rule
|
||||
nsc := namespace.NewNamespaceController(pclient, client, kubeInformer.Core().V1().Namespaces(), pInformer.Kyverno().V1alpha1().Policies(), pInformer.Kyverno().V1alpha1().PolicyViolations(), egen)
|
||||
|
||||
tlsPair, err := initTLSPemPair(clientConfig, client)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err)
|
||||
|
@ -105,9 +122,11 @@ func main() {
|
|||
}
|
||||
|
||||
pInformer.Start(stopCh)
|
||||
kubeInformer.Start(stopCh)
|
||||
go pc.Run(1, stopCh)
|
||||
go pvc.Run(1, stopCh)
|
||||
go egen.Run(1, stopCh)
|
||||
go nsc.Run(1, stopCh)
|
||||
|
||||
//TODO add WG for the go routines?
|
||||
server.RunAsync()
|
||||
|
|
|
@ -45,10 +45,10 @@ type ExcludeResources struct {
|
|||
|
||||
// ResourceDescription describes the resource to which the PolicyRule will be applied.
|
||||
type ResourceDescription struct {
|
||||
Kinds []string `json:"kinds"`
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Selector *metav1.LabelSelector `json:"selector"`
|
||||
Kinds []string `json:"kinds"`
|
||||
Name string `json:"name"`
|
||||
Namespaces []string `json:"namespaces,omitempty"`
|
||||
Selector *metav1.LabelSelector `json:"selector"`
|
||||
}
|
||||
|
||||
// Mutation describes the way how Mutating Webhook will react on resource creation
|
||||
|
|
|
@ -280,6 +280,11 @@ func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) {
|
|||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Namespaces != nil {
|
||||
in, out := &in.Namespaces, &out.Namespaces
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(v1.LabelSelector)
|
||||
|
|
|
@ -19,7 +19,7 @@ limitations under the License.
|
|||
package versioned
|
||||
|
||||
import (
|
||||
kyvernov1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1"
|
||||
kyvernov1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
|
@ -19,9 +19,9 @@ limitations under the License.
|
|||
package fake
|
||||
|
||||
import (
|
||||
clientset "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
kyvernov1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1"
|
||||
fakekyvernov1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake"
|
||||
clientset "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernov1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1"
|
||||
fakekyvernov1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
|
@ -23,9 +23,9 @@ import (
|
|||
sync "sync"
|
||||
time "time"
|
||||
|
||||
versioned "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/internalinterfaces"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/kyverno"
|
||||
versioned "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
@ -21,7 +21,7 @@ package internalinterfaces
|
|||
import (
|
||||
time "time"
|
||||
|
||||
versioned "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
versioned "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
cache "k8s.io/client-go/tools/cache"
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeKyvernoV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeKyvernoV1alpha1) Policies() v1alpha1.PolicyInterface {
|
||||
return &FakePolicies{c}
|
||||
}
|
||||
|
||||
func (c *FakeKyvernoV1alpha1) PolicyViolations() v1alpha1.PolicyViolationInterface {
|
||||
return &FakePolicyViolations{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeKyvernoV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakePolicies implements PolicyInterface
|
||||
type FakePolicies struct {
|
||||
Fake *FakeKyvernoV1alpha1
|
||||
}
|
||||
|
||||
var policiesResource = schema.GroupVersionResource{Group: "kyverno.io", Version: "v1alpha1", Resource: "policies"}
|
||||
|
||||
var policiesKind = schema.GroupVersionKind{Group: "kyverno.io", Version: "v1alpha1", Kind: "Policy"}
|
||||
|
||||
// Get takes name of the policy, and returns the corresponding policy object, and an error if there is any.
|
||||
func (c *FakePolicies) Get(name string, options v1.GetOptions) (result *v1alpha1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(policiesResource, name), &v1alpha1.Policy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.Policy), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Policies that match those selectors.
|
||||
func (c *FakePolicies) List(opts v1.ListOptions) (result *v1alpha1.PolicyList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(policiesResource, policiesKind, opts), &v1alpha1.PolicyList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.PolicyList{ListMeta: obj.(*v1alpha1.PolicyList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.PolicyList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policies.
|
||||
func (c *FakePolicies) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(policiesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a policy and creates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *FakePolicies) Create(policy *v1alpha1.Policy) (result *v1alpha1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(policiesResource, policy), &v1alpha1.Policy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.Policy), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a policy and updates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *FakePolicies) Update(policy *v1alpha1.Policy) (result *v1alpha1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(policiesResource, policy), &v1alpha1.Policy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.Policy), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakePolicies) UpdateStatus(policy *v1alpha1.Policy) (*v1alpha1.Policy, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(policiesResource, "status", policy), &v1alpha1.Policy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.Policy), err
|
||||
}
|
||||
|
||||
// Delete takes name of the policy and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePolicies) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(policiesResource, name), &v1alpha1.Policy{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakePolicies) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(policiesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.PolicyList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policy.
|
||||
func (c *FakePolicies) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(policiesResource, name, pt, data, subresources...), &v1alpha1.Policy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.Policy), err
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakePolicyViolations implements PolicyViolationInterface
|
||||
type FakePolicyViolations struct {
|
||||
Fake *FakeKyvernoV1alpha1
|
||||
}
|
||||
|
||||
var policyviolationsResource = schema.GroupVersionResource{Group: "kyverno.io", Version: "v1alpha1", Resource: "policyviolations"}
|
||||
|
||||
var policyviolationsKind = schema.GroupVersionKind{Group: "kyverno.io", Version: "v1alpha1", Kind: "PolicyViolation"}
|
||||
|
||||
// Get takes name of the policyViolation, and returns the corresponding policyViolation object, and an error if there is any.
|
||||
func (c *FakePolicyViolations) Get(name string, options v1.GetOptions) (result *v1alpha1.PolicyViolation, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(policyviolationsResource, name), &v1alpha1.PolicyViolation{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PolicyViolation), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PolicyViolations that match those selectors.
|
||||
func (c *FakePolicyViolations) List(opts v1.ListOptions) (result *v1alpha1.PolicyViolationList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(policyviolationsResource, policyviolationsKind, opts), &v1alpha1.PolicyViolationList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.PolicyViolationList{ListMeta: obj.(*v1alpha1.PolicyViolationList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.PolicyViolationList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policyViolations.
|
||||
func (c *FakePolicyViolations) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(policyviolationsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a policyViolation and creates it. Returns the server's representation of the policyViolation, and an error, if there is any.
|
||||
func (c *FakePolicyViolations) Create(policyViolation *v1alpha1.PolicyViolation) (result *v1alpha1.PolicyViolation, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(policyviolationsResource, policyViolation), &v1alpha1.PolicyViolation{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PolicyViolation), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a policyViolation and updates it. Returns the server's representation of the policyViolation, and an error, if there is any.
|
||||
func (c *FakePolicyViolations) Update(policyViolation *v1alpha1.PolicyViolation) (result *v1alpha1.PolicyViolation, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(policyviolationsResource, policyViolation), &v1alpha1.PolicyViolation{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PolicyViolation), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakePolicyViolations) UpdateStatus(policyViolation *v1alpha1.PolicyViolation) (*v1alpha1.PolicyViolation, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(policyviolationsResource, "status", policyViolation), &v1alpha1.PolicyViolation{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PolicyViolation), err
|
||||
}
|
||||
|
||||
// Delete takes name of the policyViolation and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePolicyViolations) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(policyviolationsResource, name), &v1alpha1.PolicyViolation{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakePolicyViolations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(policyviolationsResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.PolicyViolationList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policyViolation.
|
||||
func (c *FakePolicyViolations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PolicyViolation, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(policyviolationsResource, name, pt, data, subresources...), &v1alpha1.PolicyViolation{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PolicyViolation), err
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type PolicyExpansion interface{}
|
||||
|
||||
type PolicyViolationExpansion interface{}
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
"github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type KyvernoV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
PoliciesGetter
|
||||
PolicyViolationsGetter
|
||||
}
|
||||
|
||||
// KyvernoV1alpha1Client is used to interact with features provided by the kyverno.io group.
|
||||
type KyvernoV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *KyvernoV1alpha1Client) Policies() PolicyInterface {
|
||||
return newPolicies(c)
|
||||
}
|
||||
|
||||
func (c *KyvernoV1alpha1Client) PolicyViolations() PolicyViolationInterface {
|
||||
return newPolicyViolations(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new KyvernoV1alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*KyvernoV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &KyvernoV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new KyvernoV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *KyvernoV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new KyvernoV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *KyvernoV1alpha1Client {
|
||||
return &KyvernoV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *KyvernoV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
scheme "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// PoliciesGetter has a method to return a PolicyInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PoliciesGetter interface {
|
||||
Policies() PolicyInterface
|
||||
}
|
||||
|
||||
// PolicyInterface has methods to work with Policy resources.
|
||||
type PolicyInterface interface {
|
||||
Create(*v1alpha1.Policy) (*v1alpha1.Policy, error)
|
||||
Update(*v1alpha1.Policy) (*v1alpha1.Policy, error)
|
||||
UpdateStatus(*v1alpha1.Policy) (*v1alpha1.Policy, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.Policy, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.PolicyList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Policy, err error)
|
||||
PolicyExpansion
|
||||
}
|
||||
|
||||
// policies implements PolicyInterface
|
||||
type policies struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newPolicies returns a Policies
|
||||
func newPolicies(c *KyvernoV1alpha1Client) *policies {
|
||||
return &policies{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the policy, and returns the corresponding policy object, and an error if there is any.
|
||||
func (c *policies) Get(name string, options v1.GetOptions) (result *v1alpha1.Policy, err error) {
|
||||
result = &v1alpha1.Policy{}
|
||||
err = c.client.Get().
|
||||
Resource("policies").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Policies that match those selectors.
|
||||
func (c *policies) List(opts v1.ListOptions) (result *v1alpha1.PolicyList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.PolicyList{}
|
||||
err = c.client.Get().
|
||||
Resource("policies").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policies.
|
||||
func (c *policies) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("policies").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a policy and creates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *policies) Create(policy *v1alpha1.Policy) (result *v1alpha1.Policy, err error) {
|
||||
result = &v1alpha1.Policy{}
|
||||
err = c.client.Post().
|
||||
Resource("policies").
|
||||
Body(policy).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a policy and updates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *policies) Update(policy *v1alpha1.Policy) (result *v1alpha1.Policy, err error) {
|
||||
result = &v1alpha1.Policy{}
|
||||
err = c.client.Put().
|
||||
Resource("policies").
|
||||
Name(policy.Name).
|
||||
Body(policy).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *policies) UpdateStatus(policy *v1alpha1.Policy) (result *v1alpha1.Policy, err error) {
|
||||
result = &v1alpha1.Policy{}
|
||||
err = c.client.Put().
|
||||
Resource("policies").
|
||||
Name(policy.Name).
|
||||
SubResource("status").
|
||||
Body(policy).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the policy and deletes it. Returns an error if one occurs.
|
||||
func (c *policies) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("policies").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *policies) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("policies").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policy.
|
||||
func (c *policies) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Policy, err error) {
|
||||
result = &v1alpha1.Policy{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("policies").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
scheme "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// PolicyViolationsGetter has a method to return a PolicyViolationInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PolicyViolationsGetter interface {
|
||||
PolicyViolations() PolicyViolationInterface
|
||||
}
|
||||
|
||||
// PolicyViolationInterface has methods to work with PolicyViolation resources.
|
||||
type PolicyViolationInterface interface {
|
||||
Create(*v1alpha1.PolicyViolation) (*v1alpha1.PolicyViolation, error)
|
||||
Update(*v1alpha1.PolicyViolation) (*v1alpha1.PolicyViolation, error)
|
||||
UpdateStatus(*v1alpha1.PolicyViolation) (*v1alpha1.PolicyViolation, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.PolicyViolation, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.PolicyViolationList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PolicyViolation, err error)
|
||||
PolicyViolationExpansion
|
||||
}
|
||||
|
||||
// policyViolations implements PolicyViolationInterface
|
||||
type policyViolations struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newPolicyViolations returns a PolicyViolations
|
||||
func newPolicyViolations(c *KyvernoV1alpha1Client) *policyViolations {
|
||||
return &policyViolations{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the policyViolation, and returns the corresponding policyViolation object, and an error if there is any.
|
||||
func (c *policyViolations) Get(name string, options v1.GetOptions) (result *v1alpha1.PolicyViolation, err error) {
|
||||
result = &v1alpha1.PolicyViolation{}
|
||||
err = c.client.Get().
|
||||
Resource("policyviolations").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PolicyViolations that match those selectors.
|
||||
func (c *policyViolations) List(opts v1.ListOptions) (result *v1alpha1.PolicyViolationList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.PolicyViolationList{}
|
||||
err = c.client.Get().
|
||||
Resource("policyviolations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policyViolations.
|
||||
func (c *policyViolations) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("policyviolations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a policyViolation and creates it. Returns the server's representation of the policyViolation, and an error, if there is any.
|
||||
func (c *policyViolations) Create(policyViolation *v1alpha1.PolicyViolation) (result *v1alpha1.PolicyViolation, err error) {
|
||||
result = &v1alpha1.PolicyViolation{}
|
||||
err = c.client.Post().
|
||||
Resource("policyviolations").
|
||||
Body(policyViolation).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a policyViolation and updates it. Returns the server's representation of the policyViolation, and an error, if there is any.
|
||||
func (c *policyViolations) Update(policyViolation *v1alpha1.PolicyViolation) (result *v1alpha1.PolicyViolation, err error) {
|
||||
result = &v1alpha1.PolicyViolation{}
|
||||
err = c.client.Put().
|
||||
Resource("policyviolations").
|
||||
Name(policyViolation.Name).
|
||||
Body(policyViolation).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *policyViolations) UpdateStatus(policyViolation *v1alpha1.PolicyViolation) (result *v1alpha1.PolicyViolation, err error) {
|
||||
result = &v1alpha1.PolicyViolation{}
|
||||
err = c.client.Put().
|
||||
Resource("policyviolations").
|
||||
Name(policyViolation.Name).
|
||||
SubResource("status").
|
||||
Body(policyViolation).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the policyViolation and deletes it. Returns an error if one occurs.
|
||||
func (c *policyViolations) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("policyviolations").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *policyViolations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("policyviolations").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policyViolation.
|
||||
func (c *policyViolations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PolicyViolation, err error) {
|
||||
result = &v1alpha1.PolicyViolation{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("policyviolations").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package kyverno
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/kyverno/v1alpha1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// Policies returns a PolicyInformer.
|
||||
Policies() PolicyInformer
|
||||
// PolicyViolations returns a PolicyViolationInformer.
|
||||
PolicyViolations() PolicyViolationInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// Policies returns a PolicyInformer.
|
||||
func (v *version) Policies() PolicyInformer {
|
||||
return &policyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// PolicyViolations returns a PolicyViolationInformer.
|
||||
func (v *version) PolicyViolations() PolicyViolationInformer {
|
||||
return &policyViolationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
kyvernov1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
versioned "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyInformer provides access to a shared informer and lister for
|
||||
// Policies.
|
||||
type PolicyInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.PolicyLister
|
||||
}
|
||||
|
||||
type policyInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewPolicyInformer constructs a new informer for Policy type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredPolicyInformer constructs a new informer for Policy type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.KyvernoV1alpha1().Policies().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.KyvernoV1alpha1().Policies().Watch(options)
|
||||
},
|
||||
},
|
||||
&kyvernov1alpha1.Policy{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *policyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *policyInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&kyvernov1alpha1.Policy{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *policyInformer) Lister() v1alpha1.PolicyLister {
|
||||
return v1alpha1.NewPolicyLister(f.Informer().GetIndexer())
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
kyvernov1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
versioned "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyViolationInformer provides access to a shared informer and lister for
|
||||
// PolicyViolations.
|
||||
type PolicyViolationInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.PolicyViolationLister
|
||||
}
|
||||
|
||||
type policyViolationInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewPolicyViolationInformer constructs a new informer for PolicyViolation type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewPolicyViolationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyViolationInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredPolicyViolationInformer constructs a new informer for PolicyViolation type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredPolicyViolationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.KyvernoV1alpha1().PolicyViolations().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.KyvernoV1alpha1().PolicyViolations().Watch(options)
|
||||
},
|
||||
},
|
||||
&kyvernov1alpha1.PolicyViolation{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *policyViolationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyViolationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *policyViolationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&kyvernov1alpha1.PolicyViolation{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *policyViolationInformer) Lister() v1alpha1.PolicyViolationLister {
|
||||
return v1alpha1.NewPolicyViolationLister(f.Informer().GetIndexer())
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
// PolicyListerExpansion allows custom methods to be added to
|
||||
// PolicyLister.
|
||||
type PolicyListerExpansion interface {
|
||||
GetPolicyForPolicyViolation(pv *kyverno.PolicyViolation) ([]*kyverno.Policy, error)
|
||||
}
|
||||
|
||||
// PolicyViolationListerExpansion allows custom methods to be added to
|
||||
// PolicyViolationLister.
|
||||
type PolicyViolationListerExpansion interface{}
|
||||
|
||||
func (pl *policyLister) GetPolicyForPolicyViolation(pv *kyverno.PolicyViolation) ([]*kyverno.Policy, error) {
|
||||
if len(pv.Labels) == 0 {
|
||||
return nil, fmt.Errorf("no Policy found for PolicyViolation %v because it has no labels", pv.Name)
|
||||
}
|
||||
|
||||
pList, err := pl.List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var policies []*kyverno.Policy
|
||||
for _, p := range pList {
|
||||
policyLabelmap := map[string]string{"policy": p.Name}
|
||||
|
||||
ls := &metav1.LabelSelector{}
|
||||
err = metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&policyLabelmap, ls, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate label sector of Policy name %s: %v", p.Name, err)
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(ls)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
||||
}
|
||||
// If a policy with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||
if selector.Empty() || !selector.Matches(labels.Set(pv.Labels)) {
|
||||
continue
|
||||
}
|
||||
policies = append(policies, p)
|
||||
}
|
||||
|
||||
if len(policies) == 0 {
|
||||
return nil, fmt.Errorf("could not find Policy set for PolicyViolation %s with labels: %v", pv.Name, pv.Labels)
|
||||
}
|
||||
|
||||
return policies, nil
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyLister helps list Policies.
|
||||
type PolicyLister interface {
|
||||
// List lists all Policies in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.Policy, err error)
|
||||
// Get retrieves the Policy from the index for a given name.
|
||||
Get(name string) (*v1alpha1.Policy, error)
|
||||
PolicyListerExpansion
|
||||
}
|
||||
|
||||
// policyLister implements the PolicyLister interface.
|
||||
type policyLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewPolicyLister returns a new PolicyLister.
|
||||
func NewPolicyLister(indexer cache.Indexer) PolicyLister {
|
||||
return &policyLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all Policies in the indexer.
|
||||
func (s *policyLister) List(selector labels.Selector) (ret []*v1alpha1.Policy, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.Policy))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the Policy from the index for a given name.
|
||||
func (s *policyLister) Get(name string) (*v1alpha1.Policy, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("policy"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.Policy), nil
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyViolationLister helps list PolicyViolations.
|
||||
type PolicyViolationLister interface {
|
||||
// List lists all PolicyViolations in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.PolicyViolation, err error)
|
||||
// Get retrieves the PolicyViolation from the index for a given name.
|
||||
Get(name string) (*v1alpha1.PolicyViolation, error)
|
||||
PolicyViolationListerExpansion
|
||||
}
|
||||
|
||||
// policyViolationLister implements the PolicyViolationLister interface.
|
||||
type policyViolationLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewPolicyViolationLister returns a new PolicyViolationLister.
|
||||
func NewPolicyViolationLister(indexer cache.Indexer) PolicyViolationLister {
|
||||
return &policyViolationLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all PolicyViolations in the indexer.
|
||||
func (s *policyViolationLister) List(selector labels.Selector) (ret []*v1alpha1.PolicyViolation, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.PolicyViolation))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the PolicyViolation from the index for a given name.
|
||||
func (s *policyViolationLister) Get(name string) (*v1alpha1.PolicyViolation, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("policyviolation"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.PolicyViolation), nil
|
||||
}
|
|
@ -2,6 +2,7 @@ package engine
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@ -21,16 +22,18 @@ func Generate(client *client.Client, policy kyverno.Policy, ns unstructured.Unst
|
|||
if rule.Generation == (kyverno.Generation{}) {
|
||||
continue
|
||||
}
|
||||
glog.V(4).Infof("applying policy %s generate rule %s on resource %s/%s/%s", policy.Name, rule.Name, ns.GetKind(), ns.GetNamespace(), ns.GetName())
|
||||
ri := info.NewRuleInfo(rule.Name, info.Generation)
|
||||
err := applyRuleGenerator(client, ns, rule.Generation, policy.GetCreationTimestamp())
|
||||
if err != nil {
|
||||
ri.Fail()
|
||||
ri.Addf("Rule %s: Failed to apply rule generator, err %v.", rule.Name, err)
|
||||
ri.Addf("Failed to apply rule generator, err %v.", rule.Name, err)
|
||||
glog.Infof("failed to apply policy %s rule %s on resource %s/%s/%s: %v", policy.Name, rule.Name, ns.GetKind(), ns.GetNamespace(), ns.GetName(), err)
|
||||
} else {
|
||||
ri.Addf("Rule %s: Generation succesfully.", rule.Name)
|
||||
ri.Addf("Generation succesfully.", rule.Name)
|
||||
glog.Infof("succesfully applied policy %s rule %s on resource %s/%s/%s", policy.Name, rule.Name, ns.GetKind(), ns.GetNamespace(), ns.GetName())
|
||||
}
|
||||
ris = append(ris, ri)
|
||||
|
||||
}
|
||||
return ris
|
||||
}
|
||||
|
@ -45,19 +48,24 @@ func applyRuleGenerator(client *client.Client, ns unstructured.Unstructured, gen
|
|||
return nsCreationTime.Before(&policyCreationTime)
|
||||
}()
|
||||
if gen.Data != nil {
|
||||
glog.V(4).Info("generate rule: creates new resource")
|
||||
// 1> Check if resource exists
|
||||
obj, err := client.GetResource(gen.Kind, ns.GetName(), gen.Name)
|
||||
if err == nil {
|
||||
glog.V(4).Infof("generate rule: resource %s/%s/%s already present. checking if it contains the required configuration", gen.Kind, ns.GetName(), gen.Name)
|
||||
// 2> If already exsists, then verify the content is contained
|
||||
// found the resource
|
||||
// check if the rule is create, if yes, then verify if the specified configuration is present in the resource
|
||||
ok, err := checkResource(gen.Data, obj)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("generate rule:: unable to check if configuration %v, is present in resource %s/%s/%s", gen.Data, gen.Kind, ns.GetName(), gen.Name)
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("rule configuration not present in resource %s/%s", ns.GetName(), gen.Name)
|
||||
glog.V(4).Infof("generate rule:: configuration %v not present in resource %s/%s/%s", gen.Data, gen.Kind, ns.GetName(), gen.Name)
|
||||
return errors.New("rule configuration not present in resource")
|
||||
}
|
||||
glog.V(4).Infof("generate rule: required configuration %v is present in resource %s/%s/%s", gen.Data, gen.Kind, ns.GetName(), gen.Name)
|
||||
return nil
|
||||
}
|
||||
rdata, err = runtime.DefaultUnstructuredConverter.ToUnstructured(&gen.Data)
|
||||
|
@ -67,16 +75,20 @@ func applyRuleGenerator(client *client.Client, ns unstructured.Unstructured, gen
|
|||
}
|
||||
}
|
||||
if gen.Clone != (kyverno.CloneFrom{}) {
|
||||
glog.V(4).Info("generate rule: clone resource")
|
||||
// 1> Check if resource exists
|
||||
_, err := client.GetResource(gen.Kind, ns.GetName(), gen.Name)
|
||||
if err == nil {
|
||||
glog.V(4).Infof("generate rule: resource %s/%s/%s already present", gen.Kind, ns.GetName(), gen.Name)
|
||||
return nil
|
||||
}
|
||||
// 2> If already exists return
|
||||
// 2> If clone already exists return
|
||||
resource, err = client.GetResource(gen.Kind, gen.Clone.Namespace, gen.Clone.Name)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("generate rule: clone reference resource %s/%s/%s not present: %v", gen.Kind, gen.Kind, gen.Clone.Namespace, gen.Clone.Name, err)
|
||||
return err
|
||||
}
|
||||
glog.V(4).Infof("generate rule: clone reference resource %s/%s/%s present", gen.Kind, gen.Kind, gen.Clone.Namespace, gen.Clone.Name)
|
||||
rdata = resource.UnstructuredContent()
|
||||
}
|
||||
if processExisting {
|
||||
|
@ -90,11 +102,14 @@ func applyRuleGenerator(client *client.Client, ns unstructured.Unstructured, gen
|
|||
resource.SetResourceVersion("")
|
||||
_, err = client.CreateResource(gen.Kind, ns.GetName(), resource, false)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("generate rule: unable to create resource %s/%s/%s: %v", gen.Kind, resource.GetNamespace(), resource.GetName(), err)
|
||||
return err
|
||||
}
|
||||
glog.V(4).Infof("generate rule: created resource %s/%s/%s", gen.Kind, resource.GetNamespace(), resource.GetName())
|
||||
return nil
|
||||
}
|
||||
|
||||
//checkResource checks if the config is present in th eresource
|
||||
func checkResource(config interface{}, resource *unstructured.Unstructured) (bool, error) {
|
||||
var err error
|
||||
|
||||
|
@ -119,7 +134,6 @@ func checkResource(config interface{}, resource *unstructured.Unstructured) (boo
|
|||
if err != nil {
|
||||
// unable to unmarshall
|
||||
return false, err
|
||||
|
||||
}
|
||||
|
||||
var objData interface{}
|
||||
|
|
|
@ -29,7 +29,10 @@ func processOverlay(rule kyverno.Rule, rawResource []byte) ([][]byte, error) {
|
|||
if err != nil && strings.Contains(err.Error(), "Conditions are not met") {
|
||||
// glog.V(4).Infof("overlay pattern %s does not match resource %s/%s", rule.Mutation.Overlay, resourceUnstr.GetNamespace(), resourceUnstr.GetName())
|
||||
glog.Infof("Resource does not meet conditions in overlay pattern, resource=%s, rule=%s\n", resourceInfo, rule.Name)
|
||||
return nil, nil
|
||||
// patches, err := processOverlayPatches(resource, rule.Mutation.Overlay)
|
||||
// if err != nil && strings.Contains(err.Error(), "Conditions are not met") {
|
||||
// glog.V(4).Infof("overlay pattern %s does not match resource %s/%s", rule.Mutation.Overlay, resourceUnstr.GetNamespace(), resourceUnstr.GetName())
|
||||
// return nil, nil
|
||||
}
|
||||
|
||||
return patches, err
|
||||
|
|
|
@ -13,7 +13,7 @@ func patchOverlay(rule kyverno.Rule, rawResource []byte) ([][]byte, error) {
|
|||
if err := json.Unmarshal(rawResource, &resource); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO: evaluate, Unmarshall called thrice
|
||||
resourceInfo := ParseResourceInfoFromObject(rawResource)
|
||||
patches, err := processOverlayPatches(resource, rule.Mutation.Overlay)
|
||||
if err != nil && strings.Contains(err.Error(), "Conditions are not met") {
|
||||
|
|
|
@ -10,10 +10,8 @@ import (
|
|||
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/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"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -26,135 +24,135 @@ type EngineResponse struct {
|
|||
RuleInfos []info.RuleInfo
|
||||
}
|
||||
|
||||
//ListResourcesThatApplyToPolicy returns list of resources that are filtered by policy rules
|
||||
func ListResourcesThatApplyToPolicy(client *client.Client, policy *kyverno.Policy, filterK8Resources []utils.K8Resource) map[string]resourceInfo {
|
||||
// key uid
|
||||
resourceMap := map[string]resourceInfo{}
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
// Match
|
||||
for _, k := range rule.MatchResources.Kinds {
|
||||
namespaces := []string{}
|
||||
if k == "Namespace" {
|
||||
namespaces = []string{""}
|
||||
} else {
|
||||
if rule.MatchResources.Namespace != "" {
|
||||
// if namespace is specified then we add the namespace
|
||||
namespaces = append(namespaces, rule.MatchResources.Namespace)
|
||||
} else {
|
||||
// no namespace specified, refer to all namespaces
|
||||
namespaces = getAllNamespaces(client)
|
||||
}
|
||||
// //ListResourcesThatApplyToPolicy returns list of resources that are filtered by policy rules
|
||||
// func ListResourcesThatApplyToPolicy(client *client.Client, policy *kyverno.Policy, filterK8Resources []utils.K8Resource) map[string]resourceInfo {
|
||||
// // key uid
|
||||
// resourceMap := map[string]resourceInfo{}
|
||||
// for _, rule := range policy.Spec.Rules {
|
||||
// // Match
|
||||
// for _, k := range rule.MatchResources.Kinds {
|
||||
// namespaces := []string{}
|
||||
// if k == "Namespace" {
|
||||
// namespaces = []string{""}
|
||||
// } else {
|
||||
// if rule.MatchResources.Namespace != "" {
|
||||
// // if namespace is specified then we add the namespace
|
||||
// namespaces = append(namespaces, rule.MatchResources.Namespace)
|
||||
// } else {
|
||||
// // no namespace specified, refer to all namespaces
|
||||
// namespaces = getAllNamespaces(client)
|
||||
// }
|
||||
|
||||
// Check if exclude namespace is not clashing
|
||||
namespaces = excludeNamespaces(namespaces, rule.ExcludeResources.Namespace)
|
||||
}
|
||||
// // Check if exclude namespace is not clashing
|
||||
// namespaces = excludeNamespaces(namespaces, rule.ExcludeResources.Namespace)
|
||||
// }
|
||||
|
||||
// If kind is namespace then namespace is "", override
|
||||
// Get resources in the namespace
|
||||
for _, ns := range namespaces {
|
||||
rMap := getResourcesPerNamespace(k, client, ns, rule, filterK8Resources)
|
||||
mergeresources(resourceMap, rMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
return resourceMap
|
||||
}
|
||||
// // If kind is namespace then namespace is "", override
|
||||
// // Get resources in the namespace
|
||||
// for _, ns := range namespaces {
|
||||
// rMap := getResourcesPerNamespace(k, client, ns, rule, filterK8Resources)
|
||||
// mergeresources(resourceMap, rMap)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return resourceMap
|
||||
// }
|
||||
|
||||
func getResourcesPerNamespace(kind string, client *client.Client, namespace string, rule kyverno.Rule, filterK8Resources []utils.K8Resource) map[string]resourceInfo {
|
||||
resourceMap := map[string]resourceInfo{}
|
||||
// List resources
|
||||
list, err := client.ListResource(kind, namespace, rule.MatchResources.Selector)
|
||||
if err != nil {
|
||||
glog.Errorf("unable to list resource for %s with label selector %s", kind, rule.MatchResources.Selector.String())
|
||||
return nil
|
||||
}
|
||||
var selector labels.Selector
|
||||
// exclude label selector
|
||||
if rule.ExcludeResources.Selector != nil {
|
||||
selector, err = v1helper.LabelSelectorAsSelector(rule.ExcludeResources.Selector)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
}
|
||||
}
|
||||
for _, res := range list.Items {
|
||||
// exclude label selectors
|
||||
if selector != nil {
|
||||
set := labels.Set(res.GetLabels())
|
||||
if selector.Matches(set) {
|
||||
// if matches
|
||||
continue
|
||||
}
|
||||
}
|
||||
var name string
|
||||
// match
|
||||
// name
|
||||
// wild card matching
|
||||
name = rule.MatchResources.Name
|
||||
if name != "" {
|
||||
// if does not match then we skip
|
||||
if !wildcard.Match(name, res.GetName()) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
// exclude
|
||||
// name
|
||||
// wild card matching
|
||||
name = rule.ExcludeResources.Name
|
||||
if name != "nil" {
|
||||
// if matches then we skip
|
||||
if wildcard.Match(name, res.GetName()) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
gvk := res.GroupVersionKind()
|
||||
// func getResourcesPerNamespace(kind string, client *client.Client, namespace string, rule kyverno.Rule, filterK8Resources []utils.K8Resource) map[string]resourceInfo {
|
||||
// resourceMap := map[string]resourceInfo{}
|
||||
// // List resources
|
||||
// list, err := client.ListResource(kind, namespace, rule.MatchResources.Selector)
|
||||
// if err != nil {
|
||||
// glog.Errorf("unable to list resource for %s with label selector %s", kind, rule.MatchResources.Selector.String())
|
||||
// return nil
|
||||
// }
|
||||
// var selector labels.Selector
|
||||
// // exclude label selector
|
||||
// if rule.ExcludeResources.Selector != nil {
|
||||
// selector, err = v1helper.LabelSelectorAsSelector(rule.ExcludeResources.Selector)
|
||||
// if err != nil {
|
||||
// glog.Error(err)
|
||||
// }
|
||||
// }
|
||||
// for _, res := range list.Items {
|
||||
// // exclude label selectors
|
||||
// if selector != nil {
|
||||
// set := labels.Set(res.GetLabels())
|
||||
// if selector.Matches(set) {
|
||||
// // if matches
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// var name string
|
||||
// // match
|
||||
// // name
|
||||
// // wild card matching
|
||||
// name = rule.MatchResources.Name
|
||||
// if name != "" {
|
||||
// // if does not match then we skip
|
||||
// if !wildcard.Match(name, res.GetName()) {
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// // exclude
|
||||
// // name
|
||||
// // wild card matching
|
||||
// name = rule.ExcludeResources.Name
|
||||
// if name != "nil" {
|
||||
// // if matches then we skip
|
||||
// if wildcard.Match(name, res.GetName()) {
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// gvk := res.GroupVersionKind()
|
||||
|
||||
ri := resourceInfo{Resource: res, Gvk: &metav1.GroupVersionKind{Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind}}
|
||||
// Skip the filtered resources
|
||||
if utils.SkipFilteredResources(gvk.Kind, res.GetNamespace(), res.GetName(), filterK8Resources) {
|
||||
continue
|
||||
}
|
||||
// ri := resourceInfo{Resource: res, Gvk: &metav1.GroupVersionKind{Group: gvk.Group,
|
||||
// Version: gvk.Version,
|
||||
// Kind: gvk.Kind}}
|
||||
// // Skip the filtered resources
|
||||
// if utils.SkipFilteredResources(gvk.Kind, res.GetNamespace(), res.GetName(), filterK8Resources) {
|
||||
// continue
|
||||
// }
|
||||
|
||||
resourceMap[string(res.GetUID())] = ri
|
||||
}
|
||||
return resourceMap
|
||||
}
|
||||
// resourceMap[string(res.GetUID())] = ri
|
||||
// }
|
||||
// return resourceMap
|
||||
// }
|
||||
|
||||
// merge b into a map
|
||||
func mergeresources(a, b map[string]resourceInfo) {
|
||||
for k, v := range b {
|
||||
a[k] = v
|
||||
}
|
||||
}
|
||||
// // merge b into a map
|
||||
// func mergeresources(a, b map[string]resourceInfo) {
|
||||
// for k, v := range b {
|
||||
// a[k] = v
|
||||
// }
|
||||
// }
|
||||
|
||||
func getAllNamespaces(client *client.Client) []string {
|
||||
namespaces := []string{}
|
||||
// get all namespaces
|
||||
nsList, err := client.ListResource("Namespace", "", nil)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return namespaces
|
||||
}
|
||||
for _, ns := range nsList.Items {
|
||||
namespaces = append(namespaces, ns.GetName())
|
||||
}
|
||||
return namespaces
|
||||
}
|
||||
// func getAllNamespaces(client *client.Client) []string {
|
||||
// namespaces := []string{}
|
||||
// // get all namespaces
|
||||
// nsList, err := client.ListResource("Namespace", "", nil)
|
||||
// if err != nil {
|
||||
// glog.Error(err)
|
||||
// return namespaces
|
||||
// }
|
||||
// for _, ns := range nsList.Items {
|
||||
// namespaces = append(namespaces, ns.GetName())
|
||||
// }
|
||||
// return namespaces
|
||||
// }
|
||||
|
||||
func excludeNamespaces(namespaces []string, excludeNs string) []string {
|
||||
if excludeNs == "" {
|
||||
return namespaces
|
||||
}
|
||||
filteredNamespaces := []string{}
|
||||
for _, n := range namespaces {
|
||||
if n == excludeNs {
|
||||
continue
|
||||
}
|
||||
filteredNamespaces = append(filteredNamespaces, n)
|
||||
}
|
||||
return filteredNamespaces
|
||||
}
|
||||
// func excludeNamespaces(namespaces []string, excludeNs string) []string {
|
||||
// if excludeNs == "" {
|
||||
// return namespaces
|
||||
// }
|
||||
// filteredNamespaces := []string{}
|
||||
// for _, n := range namespaces {
|
||||
// if n == excludeNs {
|
||||
// continue
|
||||
// }
|
||||
// filteredNamespaces = append(filteredNamespaces, n)
|
||||
// }
|
||||
// return filteredNamespaces
|
||||
// }
|
||||
|
||||
//MatchesResourceDescription checks if the resource matches resource desription of the rule or not
|
||||
func MatchesResourceDescription(resource unstructured.Unstructured, rule kyverno.Rule) bool {
|
||||
|
@ -165,8 +163,8 @@ func MatchesResourceDescription(resource unstructured.Unstructured, rule kyverno
|
|||
return false
|
||||
}
|
||||
|
||||
// meta := parseMetadataFromObject(resourceRaw)
|
||||
name := resource.GetName()
|
||||
|
||||
namespace := resource.GetNamespace()
|
||||
|
||||
if matches.Name != "" {
|
||||
|
@ -182,14 +180,18 @@ func MatchesResourceDescription(resource unstructured.Unstructured, rule kyverno
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Matches
|
||||
if matches.Namespace != "" && matches.Namespace != namespace {
|
||||
// check if the resource namespace is defined in the list of namespaces for inclusion
|
||||
if len(matches.Namespaces) > 0 && !utils.Contains(matches.Namespaces, namespace) {
|
||||
return false
|
||||
}
|
||||
// Exclude
|
||||
if exclude.Namespace != "" && exclude.Namespace == namespace {
|
||||
// check if the resource namespace is defined in the list of namespace for exclusion
|
||||
if len(exclude.Namespaces) > 0 && utils.Contains(exclude.Namespaces, namespace) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Matches
|
||||
if matches.Selector != nil {
|
||||
selector, err := metav1.LabelSelectorAsSelector(matches.Selector)
|
||||
|
@ -216,82 +218,74 @@ func MatchesResourceDescription(resource unstructured.Unstructured, rule kyverno
|
|||
return true
|
||||
}
|
||||
|
||||
// ResourceMeetsDescription checks requests kind, name and labels to fit the policy rule
|
||||
func ResourceMeetsDescription(resourceRaw []byte, matches kyverno.ResourceDescription, exclude kyverno.ResourceDescription, gvk metav1.GroupVersionKind) bool {
|
||||
if !findKind(matches.Kinds, gvk.Kind) {
|
||||
return false
|
||||
}
|
||||
// // ResourceMeetsDescription checks requests kind, name and labels to fit the policy rule
|
||||
// func ResourceMeetsDescription(resourceRaw []byte, matches kyverno.ResourceDescription, exclude kyverno.ResourceDescription, gvk metav1.GroupVersionKind) bool {
|
||||
// if !findKind(matches.Kinds, gvk.Kind) {
|
||||
// return false
|
||||
// }
|
||||
|
||||
if resourceRaw != nil {
|
||||
meta := parseMetadataFromObject(resourceRaw)
|
||||
name := ParseNameFromObject(resourceRaw)
|
||||
namespace := ParseNamespaceFromObject(resourceRaw)
|
||||
// if resourceRaw != nil {
|
||||
// meta := parseMetadataFromObject(resourceRaw)
|
||||
// name := ParseNameFromObject(resourceRaw)
|
||||
// namespace := ParseNamespaceFromObject(resourceRaw)
|
||||
|
||||
if matches.Name != "" {
|
||||
// Matches
|
||||
if !wildcard.Match(matches.Name, name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// Exclude
|
||||
// the resource name matches the exclude resource name then reject
|
||||
if exclude.Name != "" {
|
||||
if wildcard.Match(exclude.Name, name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// Matches
|
||||
if matches.Namespace != "" && matches.Namespace != namespace {
|
||||
return false
|
||||
}
|
||||
// Exclude
|
||||
if exclude.Namespace != "" && exclude.Namespace == namespace {
|
||||
return false
|
||||
}
|
||||
// Matches
|
||||
if matches.Selector != nil {
|
||||
selector, err := metav1.LabelSelectorAsSelector(matches.Selector)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return false
|
||||
}
|
||||
if meta != nil {
|
||||
labelMap := parseLabelsFromMetadata(meta)
|
||||
if !selector.Matches(labelMap) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
// Exclude
|
||||
if exclude.Selector != nil {
|
||||
selector, err := metav1.LabelSelectorAsSelector(exclude.Selector)
|
||||
// if the label selector is incorrect, should be fail or
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return false
|
||||
}
|
||||
// if matches.Name != "" {
|
||||
// // Matches
|
||||
// if !wildcard.Match(matches.Name, name) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// // Exclude
|
||||
// // the resource name matches the exclude resource name then reject
|
||||
// if exclude.Name != "" {
|
||||
// if wildcard.Match(exclude.Name, name) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// // Matches
|
||||
// // check if the resource namespace is defined in the list of namespaces for inclusion
|
||||
// if len(matches.Namespaces) > 0 && !utils.Contains(matches.Namespaces, namespace) {
|
||||
// return false
|
||||
// }
|
||||
// // Exclude
|
||||
// // check if the resource namespace is defined in the list of namespace for exclusion
|
||||
// if len(exclude.Namespaces) > 0 && utils.Contains(exclude.Namespaces, namespace) {
|
||||
// return false
|
||||
// }
|
||||
// // Matches
|
||||
// if matches.Selector != nil {
|
||||
// selector, err := metav1.LabelSelectorAsSelector(matches.Selector)
|
||||
// if err != nil {
|
||||
// glog.Error(err)
|
||||
// return false
|
||||
// }
|
||||
// if meta != nil {
|
||||
// labelMap := parseLabelsFromMetadata(meta)
|
||||
// if !selector.Matches(labelMap) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // Exclude
|
||||
// if exclude.Selector != nil {
|
||||
// selector, err := metav1.LabelSelectorAsSelector(exclude.Selector)
|
||||
// // if the label selector is incorrect, should be fail or
|
||||
// if err != nil {
|
||||
// glog.Error(err)
|
||||
// return false
|
||||
// }
|
||||
|
||||
if meta != nil {
|
||||
labelMap := parseLabelsFromMetadata(meta)
|
||||
if selector.Matches(labelMap) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
// if meta != nil {
|
||||
// labelMap := parseLabelsFromMetadata(meta)
|
||||
// if selector.Matches(labelMap) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func parseMetadataFromObject(bytes []byte) map[string]interface{} {
|
||||
var objectJSON map[string]interface{}
|
||||
json.Unmarshal(bytes, &objectJSON)
|
||||
meta, ok := objectJSON["metadata"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return meta
|
||||
}
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
|
||||
// ParseResourceInfoFromObject get kind/namepace/name from resource
|
||||
func ParseResourceInfoFromObject(rawResource []byte) string {
|
||||
|
@ -310,18 +304,6 @@ func ParseKindFromObject(bytes []byte) string {
|
|||
return objectJSON["kind"].(string)
|
||||
}
|
||||
|
||||
func parseLabelsFromMetadata(meta map[string]interface{}) labels.Set {
|
||||
if interfaceMap, ok := meta["labels"].(map[string]interface{}); ok {
|
||||
labelMap := make(labels.Set, len(interfaceMap))
|
||||
|
||||
for key, value := range interfaceMap {
|
||||
labelMap[key] = value.(string)
|
||||
}
|
||||
return labelMap
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//ParseNameFromObject extracts resource name from JSON obj
|
||||
func ParseNameFromObject(bytes []byte) string {
|
||||
var objectJSON map[string]interface{}
|
||||
|
@ -361,15 +343,6 @@ func ParseNamespaceFromObject(bytes []byte) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// ParseRegexPolicyResourceName returns true if policyResourceName is a regexp
|
||||
func ParseRegexPolicyResourceName(policyResourceName string) (string, bool) {
|
||||
regex := strings.Split(policyResourceName, "regex:")
|
||||
if len(regex) == 1 {
|
||||
return regex[0], false
|
||||
}
|
||||
return strings.Trim(regex[1], " "), true
|
||||
}
|
||||
|
||||
func getAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
types "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
"gotest.tools/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestResourceMeetsDescription_Kind(t *testing.T) {
|
||||
|
@ -338,6 +337,336 @@ func TestResourceMeetsDescription_MatchLabelsAndMatchExpressions(t *testing.T) {
|
|||
|
||||
assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
}
|
||||
// func TestResourceMeetsDescription_Kind(t *testing.T) {
|
||||
// resourceName := "test-config-map"
|
||||
// resourceDescription := types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: nil,
|
||||
// MatchExpressions: nil,
|
||||
// },
|
||||
// }
|
||||
// excludeResourcesResourceDesc := types.ResourceDescription{}
|
||||
// groupVersionKind := metav1.GroupVersionKind{Kind: "ConfigMap"}
|
||||
|
||||
// rawResource := []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// resourceDescription.Kinds[0] = "Deployment"
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// resourceDescription.Kinds[0] = "ConfigMap"
|
||||
// groupVersionKind.Kind = "Deployment"
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// }
|
||||
|
||||
// func TestResourceMeetsDescription_Name(t *testing.T) {
|
||||
// resourceName := "test-config-map"
|
||||
// resourceDescription := types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: nil,
|
||||
// MatchExpressions: nil,
|
||||
// },
|
||||
// }
|
||||
// excludeResourcesResourceDesc := types.ResourceDescription{}
|
||||
|
||||
// groupVersionKind := metav1.GroupVersionKind{Kind: "ConfigMap"}
|
||||
|
||||
// rawResource := []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// resourceName = "test-config-map-new"
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// rawResource = []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map-new",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// rawResource = []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// }
|
||||
|
||||
// func TestResourceMeetsDescription_MatchExpressions(t *testing.T) {
|
||||
// resourceName := "test-config-map"
|
||||
// resourceDescription := types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: nil,
|
||||
// MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label2",
|
||||
// Operator: "NotIn",
|
||||
// Values: []string{
|
||||
// "sometest1",
|
||||
// },
|
||||
// },
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label1",
|
||||
// Operator: "In",
|
||||
// Values: []string{
|
||||
// "test1",
|
||||
// "test8",
|
||||
// "test201",
|
||||
// },
|
||||
// },
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label3",
|
||||
// Operator: "DoesNotExist",
|
||||
// Values: nil,
|
||||
// },
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label2",
|
||||
// Operator: "In",
|
||||
// Values: []string{
|
||||
// "test2",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// excludeResourcesResourceDesc := types.ResourceDescription{}
|
||||
|
||||
// groupVersionKind := metav1.GroupVersionKind{Kind: "ConfigMap"}
|
||||
// rawResource := []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// rawResource = []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1234567890",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// }
|
||||
|
||||
// func TestResourceMeetsDescription_MatchLabels(t *testing.T) {
|
||||
// resourceName := "test-config-map"
|
||||
// resourceDescription := types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: map[string]string{
|
||||
// "label1": "test1",
|
||||
// "label2": "test2",
|
||||
// },
|
||||
// MatchExpressions: nil,
|
||||
// },
|
||||
// }
|
||||
// groupVersionKind := metav1.GroupVersionKind{Kind: "ConfigMap"}
|
||||
// excludeResourcesResourceDesc := types.ResourceDescription{}
|
||||
|
||||
// rawResource := []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// rawResource = []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label3":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// resourceDescription = types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: map[string]string{
|
||||
// "label3": "test1",
|
||||
// "label2": "test2",
|
||||
// },
|
||||
// MatchExpressions: nil,
|
||||
// },
|
||||
// }
|
||||
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// }
|
||||
|
||||
// func TestResourceMeetsDescription_MatchLabelsAndMatchExpressions(t *testing.T) {
|
||||
// resourceName := "test-config-map"
|
||||
// resourceDescription := types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: map[string]string{
|
||||
// "label1": "test1",
|
||||
// },
|
||||
// MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label2",
|
||||
// Operator: "In",
|
||||
// Values: []string{
|
||||
// "test2",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// groupVersionKind := metav1.GroupVersionKind{Kind: "ConfigMap"}
|
||||
// excludeResourcesResourceDesc := types.ResourceDescription{}
|
||||
|
||||
// rawResource := []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// resourceDescription = types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: map[string]string{
|
||||
// "label1": "test1",
|
||||
// },
|
||||
// MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label2",
|
||||
// Operator: "NotIn",
|
||||
// Values: []string{
|
||||
// "sometest1",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
// rawResource = []byte(`{
|
||||
// "metadata":{
|
||||
// "name":"test-config-map",
|
||||
// "namespace":"default",
|
||||
// "creationTimestamp":null,
|
||||
// "labels":{
|
||||
// "label1":"test1",
|
||||
// "label2":"test2"
|
||||
// }
|
||||
// }
|
||||
// }`)
|
||||
// assert.Assert(t, ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// resourceDescription = types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: map[string]string{
|
||||
// "label1": "test1",
|
||||
// },
|
||||
// MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label2",
|
||||
// Operator: "In",
|
||||
// Values: []string{
|
||||
// "sometest1",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
|
||||
// resourceDescription = types.ResourceDescription{
|
||||
// Kinds: []string{"ConfigMap"},
|
||||
// Name: &resourceName,
|
||||
// Selector: &metav1.LabelSelector{
|
||||
// MatchLabels: map[string]string{
|
||||
// "label1": "test1",
|
||||
// "label3": "test3",
|
||||
// },
|
||||
// MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
// metav1.LabelSelectorRequirement{
|
||||
// Key: "label2",
|
||||
// Operator: "In",
|
||||
// Values: []string{
|
||||
// "test2",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
// assert.Assert(t, false == ResourceMeetsDescription(rawResource, resourceDescription, excludeResourcesResourceDesc, groupVersionKind))
|
||||
// }
|
||||
|
||||
func TestWrappedWithParentheses_StringIsWrappedWithParentheses(t *testing.T) {
|
||||
str := "(something)"
|
||||
|
|
|
@ -5,10 +5,9 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
policyscheme "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
informer "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/kyverno/v1alpha1"
|
||||
lister "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
"github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
@ -22,7 +21,7 @@ import (
|
|||
//Generator generate events
|
||||
type Generator struct {
|
||||
client *client.Client
|
||||
pLister lister.PolicyLister
|
||||
pLister kyvernolister.PolicyLister
|
||||
queue workqueue.RateLimitingInterface
|
||||
recorder record.EventRecorder
|
||||
}
|
||||
|
@ -34,7 +33,7 @@ type Interface interface {
|
|||
|
||||
//NewEventGenerator to generate a new event controller
|
||||
func NewEventGenerator(client *client.Client,
|
||||
pInformer informer.PolicyInformer) *Generator {
|
||||
pInformer kyvernoinformer.PolicyInformer) *Generator {
|
||||
|
||||
gen := Generator{
|
||||
client: client,
|
||||
|
@ -48,7 +47,7 @@ func NewEventGenerator(client *client.Client,
|
|||
|
||||
func initRecorder(client *client.Client) record.EventRecorder {
|
||||
// Initliaze Event Broadcaster
|
||||
err := policyscheme.AddToScheme(scheme.Scheme)
|
||||
err := scheme.AddToScheme(scheme.Scheme)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package gencontroller
|
||||
|
||||
import (
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
const (
|
||||
wqNamespace string = "namespace"
|
||||
workerCount int = 1
|
||||
wqRetryLimit int = 5
|
||||
policyKind string = "Policy"
|
||||
)
|
||||
|
||||
func namespaceMeetsRuleDescription(ns *corev1.Namespace, resourceDescription v1alpha1.ResourceDescription) bool {
|
||||
//REWORK Not needed but verify the 'Namespace' is defined in the list of supported kinds
|
||||
if !findKind(resourceDescription.Kinds, "Namespace") {
|
||||
return false
|
||||
}
|
||||
if resourceDescription.Name != nil {
|
||||
if !wildcard.Match(*resourceDescription.Name, ns.Name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if resourceDescription.Selector != nil {
|
||||
selector, err := metav1.LabelSelectorAsSelector(resourceDescription.Selector)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
labelSet := convertLabelsToLabelSet(ns.Labels)
|
||||
// labels
|
||||
if !selector.Matches(labelSet) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func convertLabelsToLabelSet(labelMap map[string]string) labels.Set {
|
||||
labelSet := make(labels.Set, len(labelMap))
|
||||
// REWORK: check if the below works
|
||||
// if x, ok := labelMap.(labels.Set); !ok {
|
||||
|
||||
// }
|
||||
for k, v := range labelMap {
|
||||
labelSet[k] = v
|
||||
}
|
||||
return labelSet
|
||||
}
|
||||
|
||||
func findKind(kinds []string, kindGVK string) bool {
|
||||
for _, kind := range kinds {
|
||||
if kind == kindGVK {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
205
pkg/namespace/controller.go
Normal file
205
pkg/namespace/controller.go
Normal file
|
@ -0,0 +1,205 @@
|
|||
package namespace
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"github.com/golang/glog"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"github.com/nirmata/kyverno/pkg/event"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
v1Informer "k8s.io/client-go/informers/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxRetries is the number of times a Namespace will be processed for a policy before its dropped from the queue
|
||||
maxRetries = 15
|
||||
)
|
||||
|
||||
//NamespaceController watches the 'Namespace' resource creation/update and applied the generation rules on them
|
||||
type NamespaceController struct {
|
||||
client *client.Client
|
||||
kyvernoClient *kyvernoclient.Clientset
|
||||
syncHandler func(nsKey string) error
|
||||
enqueueNs func(ns *v1.Namespace)
|
||||
|
||||
//nsLister provides expansion to the namespace lister to inject GVK for the resource
|
||||
nsLister NamespaceListerExpansion
|
||||
// nLsister can list/get namespaces from the shared informer's store
|
||||
// nsLister v1CoreLister.NamespaceLister
|
||||
// nsListerSynced returns true if the Namespace store has been synced at least once
|
||||
nsListerSynced cache.InformerSynced
|
||||
// pvLister can list/get policy violation from the shared informer's store
|
||||
pLister kyvernolister.PolicyLister
|
||||
// pvListerSynced retrns true if the Policy store has been synced at least once
|
||||
pvListerSynced cache.InformerSynced
|
||||
// pvLister can list/get policy violation from the shared informer's store
|
||||
pvLister kyvernolister.PolicyViolationLister
|
||||
|
||||
// eventGen provides interface to generate evenets
|
||||
eventGen event.Interface
|
||||
// Namespaces that need to be synced
|
||||
queue workqueue.RateLimitingInterface
|
||||
// Resource manager, manages the mapping for already processed resource
|
||||
rm resourceManager
|
||||
}
|
||||
|
||||
//NewNamespaceController returns a new Controller to manage generation rules
|
||||
func NewNamespaceController(kyvernoClient *kyvernoclient.Clientset,
|
||||
client *client.Client,
|
||||
nsInformer v1Informer.NamespaceInformer,
|
||||
pInformer kyvernoinformer.PolicyInformer,
|
||||
pvInformer kyvernoinformer.PolicyViolationInformer,
|
||||
eventGen event.Interface) *NamespaceController {
|
||||
//TODO: do we need to event recorder for this controller?
|
||||
// create the controller
|
||||
nsc := &NamespaceController{
|
||||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
eventGen: eventGen,
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespace"),
|
||||
}
|
||||
|
||||
nsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: nsc.addNamespace,
|
||||
UpdateFunc: nsc.updateNamespace,
|
||||
DeleteFunc: nsc.deleteNamespace,
|
||||
})
|
||||
|
||||
nsc.enqueueNs = nsc.enqueue
|
||||
nsc.syncHandler = nsc.syncNamespace
|
||||
|
||||
nsc.nsLister = NewNamespaceLister(nsInformer.Lister())
|
||||
nsc.nsListerSynced = nsInformer.Informer().HasSynced
|
||||
nsc.pLister = pInformer.Lister()
|
||||
nsc.pvListerSynced = pInformer.Informer().HasSynced
|
||||
nsc.pvLister = pvInformer.Lister()
|
||||
|
||||
// resource manager
|
||||
// rebuild after 300 seconds/ 5 mins
|
||||
nsc.rm = NewResourceManager(300)
|
||||
|
||||
return nsc
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) addNamespace(obj interface{}) {
|
||||
ns := obj.(*v1.Namespace)
|
||||
glog.V(4).Infof("Adding Namespace %s", ns.Name)
|
||||
nsc.enqueueNs(ns)
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) updateNamespace(old, cur interface{}) {
|
||||
oldNs := old.(*v1.Namespace)
|
||||
curNs := cur.(*v1.Namespace)
|
||||
if curNs.ResourceVersion == oldNs.ResourceVersion {
|
||||
// Periodic resync will send update events for all known Namespace.
|
||||
// Two different versions of the same replica set will always have different RVs.
|
||||
return
|
||||
}
|
||||
glog.V(4).Infof("Updating Namesapce %s", curNs.Name)
|
||||
//TODO: anything to be done here?
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) deleteNamespace(obj interface{}) {
|
||||
ns, _ := obj.(*v1.Namespace)
|
||||
glog.V(4).Infof("Deleting Namespace %s", ns.Name)
|
||||
//TODO: anything to be done here?
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) enqueue(ns *v1.Namespace) {
|
||||
key, err := cache.MetaNamespaceKeyFunc(ns)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
nsc.queue.Add(key)
|
||||
}
|
||||
|
||||
//Run to run the controller
|
||||
func (nsc *NamespaceController) Run(workers int, stopCh <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer nsc.queue.ShutDown()
|
||||
|
||||
glog.Info("Starting namespace controller")
|
||||
defer glog.Info("Shutting down namespace controller")
|
||||
|
||||
if ok := cache.WaitForCacheSync(stopCh, nsc.nsListerSynced); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < workerCount; i++ {
|
||||
go wait.Until(nsc.worker, time.Second, stopCh)
|
||||
}
|
||||
<-stopCh
|
||||
}
|
||||
|
||||
// worker runs a worker thread that just dequeues items, processes them, and marks them done.
|
||||
// It enforces that the syncHandler is never invoked concurrently with the same key.
|
||||
func (nsc *NamespaceController) worker() {
|
||||
for nsc.processNextWorkItem() {
|
||||
}
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) processNextWorkItem() bool {
|
||||
key, quit := nsc.queue.Get()
|
||||
if quit {
|
||||
return false
|
||||
}
|
||||
defer nsc.queue.Done(key)
|
||||
|
||||
err := nsc.syncHandler(key.(string))
|
||||
nsc.handleErr(err, key)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) handleErr(err error, key interface{}) {
|
||||
if err == nil {
|
||||
nsc.queue.Forget(key)
|
||||
return
|
||||
}
|
||||
|
||||
if nsc.queue.NumRequeues(key) < maxRetries {
|
||||
glog.V(2).Infof("Error syncing namespace %v: %v", key, err)
|
||||
nsc.queue.AddRateLimited(key)
|
||||
return
|
||||
}
|
||||
|
||||
utilruntime.HandleError(err)
|
||||
glog.V(2).Infof("Dropping namespace %q out of the queue: %v", key, err)
|
||||
nsc.queue.Forget(key)
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) syncNamespace(key string) error {
|
||||
startTime := time.Now()
|
||||
glog.V(4).Infof("Started syncing namespace %q (%v)", key, startTime)
|
||||
defer func() {
|
||||
glog.V(4).Infof("Finished syncing namespace %q (%v)", key, time.Since(startTime))
|
||||
}()
|
||||
namespace, err := nsc.nsLister.GetResource(key)
|
||||
if errors.IsNotFound(err) {
|
||||
glog.V(2).Infof("namespace %v has been deleted", key)
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Deep-copy otherwise we are mutating our cache.
|
||||
// TODO: Deep-copy only when needed.
|
||||
n := namespace.DeepCopy()
|
||||
|
||||
// process generate rules
|
||||
policyInfos := nsc.processNamespace(*n)
|
||||
// report errors
|
||||
nsc.report(policyInfos)
|
||||
return nil
|
||||
}
|
46
pkg/namespace/expansion.go
Normal file
46
pkg/namespace/expansion.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package namespace
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
v1CoreLister "k8s.io/client-go/listers/core/v1"
|
||||
)
|
||||
|
||||
//NamespaceListerExpansion ...
|
||||
type NamespaceListerExpansion interface {
|
||||
v1CoreLister.NamespaceLister
|
||||
// List lists all Namespaces in the indexer.
|
||||
ListResources(selector labels.Selector) (ret []*v1.Namespace, err error)
|
||||
// GetsResource and injects gvk
|
||||
GetResource(name string) (*v1.Namespace, error)
|
||||
}
|
||||
|
||||
//NamespaceLister ...
|
||||
type NamespaceLister struct {
|
||||
v1CoreLister.NamespaceLister
|
||||
}
|
||||
|
||||
//NewNamespaceLister returns a new NamespaceLister
|
||||
func NewNamespaceLister(nsLister v1CoreLister.NamespaceLister) NamespaceListerExpansion {
|
||||
nsl := NamespaceLister{
|
||||
nsLister,
|
||||
}
|
||||
return &nsl
|
||||
}
|
||||
|
||||
//ListResources is a wrapper to List and adds the resource kind information
|
||||
// as the lister is specific to a gvk we can harcode the values here
|
||||
func (nsl *NamespaceLister) ListResources(selector labels.Selector) (ret []*v1.Namespace, err error) {
|
||||
namespaces, err := nsl.List(selector)
|
||||
for index := range namespaces {
|
||||
namespaces[index].SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("Namespace"))
|
||||
}
|
||||
return namespaces, err
|
||||
}
|
||||
|
||||
//GetResource is a wrapper to get the resource and inject the GVK
|
||||
func (nsl *NamespaceLister) GetResource(name string) (*v1.Namespace, error) {
|
||||
namespace, err := nsl.Get(name)
|
||||
namespace.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("Namespace"))
|
||||
return namespace, err
|
||||
}
|
155
pkg/namespace/generation.go
Normal file
155
pkg/namespace/generation.go
Normal file
|
@ -0,0 +1,155 @@
|
|||
package namespace
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"github.com/nirmata/kyverno/pkg/engine"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
"github.com/nirmata/kyverno/pkg/info"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type resourceManager interface {
|
||||
ProcessResource(policy, pv, kind, ns, name, rv string) bool
|
||||
//TODO removeResource(kind, ns, name string) error
|
||||
RegisterResource(policy, pv, kind, ns, name, rv string)
|
||||
// reload
|
||||
Drop()
|
||||
}
|
||||
|
||||
// ResourceManager stores the details on already processed resources for caching
|
||||
type ResourceManager struct {
|
||||
// we drop and re-build the cache
|
||||
// based on the memory consumer of by the map
|
||||
data map[string]interface{}
|
||||
mux sync.RWMutex
|
||||
time time.Time
|
||||
rebuildTime int64 // after how many seconds should we rebuild the cache
|
||||
}
|
||||
|
||||
//NewResourceManager returns a new ResourceManager
|
||||
func NewResourceManager(rebuildTime int64) *ResourceManager {
|
||||
rm := ResourceManager{
|
||||
data: make(map[string]interface{}),
|
||||
time: time.Now(),
|
||||
rebuildTime: rebuildTime,
|
||||
}
|
||||
// set time it was built
|
||||
return &rm
|
||||
}
|
||||
|
||||
var empty struct{}
|
||||
|
||||
//RegisterResource stores if the policy is processed on this resource version
|
||||
func (rm *ResourceManager) RegisterResource(policy, pv, kind, ns, name, rv string) {
|
||||
rm.mux.Lock()
|
||||
defer rm.mux.Unlock()
|
||||
// add the resource
|
||||
key := buildKey(policy, pv, kind, ns, name, rv)
|
||||
rm.data[key] = empty
|
||||
}
|
||||
|
||||
//ProcessResource returns true if the policy was not applied on the resource
|
||||
func (rm *ResourceManager) ProcessResource(policy, pv, kind, ns, name, rv string) bool {
|
||||
rm.mux.RLock()
|
||||
defer rm.mux.RUnlock()
|
||||
|
||||
key := buildKey(policy, pv, kind, ns, name, rv)
|
||||
_, ok := rm.data[key]
|
||||
return ok == false
|
||||
}
|
||||
|
||||
//Drop drop the cache after every rebuild interval mins
|
||||
//TODO: or drop based on the size
|
||||
func (rm *ResourceManager) Drop() {
|
||||
timeSince := time.Since(rm.time)
|
||||
glog.V(4).Infof("time since last cache reset time %v is %v", rm.time, timeSince)
|
||||
glog.V(4).Infof("cache rebuild time %v", time.Duration(rm.rebuildTime)*time.Second)
|
||||
if timeSince > time.Duration(rm.rebuildTime)*time.Second {
|
||||
rm.mux.Lock()
|
||||
defer rm.mux.Unlock()
|
||||
rm.data = map[string]interface{}{}
|
||||
rm.time = time.Now()
|
||||
glog.V(4).Infof("dropping cache at time %v", rm.time)
|
||||
}
|
||||
}
|
||||
func buildKey(policy, pv, kind, ns, name, rv string) string {
|
||||
return policy + "/" + pv + "/" + kind + "/" + ns + "/" + name + "/" + rv
|
||||
}
|
||||
|
||||
func (nsc *NamespaceController) processNamespace(namespace corev1.Namespace) []info.PolicyInfo {
|
||||
var policyInfos []info.PolicyInfo
|
||||
// convert to unstructured
|
||||
unstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&namespace)
|
||||
if err != nil {
|
||||
glog.Infof("unable to convert to unstructured, not processing any policies: %v", err)
|
||||
return policyInfos
|
||||
}
|
||||
nsc.rm.Drop()
|
||||
|
||||
ns := unstructured.Unstructured{Object: unstr}
|
||||
|
||||
// get all the policies that have a generate rule and resource description satifies the namespace
|
||||
// apply policy on resource
|
||||
policies := listpolicies(ns, nsc.pLister)
|
||||
for _, policy := range policies {
|
||||
// pre-processing, check if the policy and resource version has been processed before
|
||||
if !nsc.rm.ProcessResource(policy.Name, policy.ResourceVersion, ns.GetKind(), ns.GetNamespace(), ns.GetName(), ns.GetResourceVersion()) {
|
||||
glog.V(4).Infof("policy %s with resource version %s already processed on resource %s/%s/%s with resource version %s", policy.Name, policy.ResourceVersion, ns.GetKind(), ns.GetNamespace(), ns.GetName(), ns.GetResourceVersion())
|
||||
continue
|
||||
}
|
||||
policyInfo := applyPolicy(nsc.client, ns, *policy)
|
||||
policyInfos = append(policyInfos, policyInfo)
|
||||
// post-processing, register the resource as processed
|
||||
nsc.rm.RegisterResource(policy.GetName(), policy.GetResourceVersion(), ns.GetKind(), ns.GetNamespace(), ns.GetName(), ns.GetResourceVersion())
|
||||
}
|
||||
return policyInfos
|
||||
}
|
||||
|
||||
func listpolicies(ns unstructured.Unstructured, pLister kyvernolister.PolicyLister) []*kyverno.Policy {
|
||||
var filteredpolicies []*kyverno.Policy
|
||||
glog.V(4).Infof("listing policies for namespace %s", ns.GetName())
|
||||
policies, err := pLister.List(labels.NewSelector())
|
||||
if err != nil {
|
||||
glog.Errorf("failed to get list policies: %v", err)
|
||||
return nil
|
||||
}
|
||||
for _, policy := range policies {
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
if rule.Generation == (kyverno.Generation{}) {
|
||||
continue
|
||||
}
|
||||
ok := engine.MatchesResourceDescription(ns, rule)
|
||||
if !ok {
|
||||
glog.V(4).Infof("namespace %s does not satisfy the resource description for the policy %s rule %s", ns.GetName(), policy.Name, rule.Name)
|
||||
continue
|
||||
}
|
||||
glog.V(4).Infof("namespace %s satisfies resource description for policy %s rule %s", ns.GetName(), policy.Name, rule.Name)
|
||||
filteredpolicies = append(filteredpolicies, policy)
|
||||
}
|
||||
}
|
||||
return filteredpolicies
|
||||
}
|
||||
|
||||
func applyPolicy(client *client.Client, resource unstructured.Unstructured, policy kyverno.Policy) info.PolicyInfo {
|
||||
startTime := time.Now()
|
||||
glog.V(4).Infof("Started apply policy %s on resource %s/%s/%s (%v)", policy.Name, resource.GetKind(), resource.GetNamespace(), resource.GetName(), startTime)
|
||||
defer func() {
|
||||
glog.V(4).Infof("Finished applying %s on resource %s/%s/%s (%v)", policy.Name, resource.GetKind(), resource.GetNamespace(), resource.GetName(), time.Since(startTime))
|
||||
}()
|
||||
policyInfo := info.NewPolicyInfo(policy.Name, resource.GetKind(), resource.GetName(), resource.GetNamespace(), policy.Spec.ValidationFailureAction)
|
||||
ruleInfos := engine.Generate(client, policy, resource)
|
||||
policyInfo.AddRuleInfos(ruleInfos)
|
||||
|
||||
return policyInfo
|
||||
}
|
59
pkg/namespace/report.go
Normal file
59
pkg/namespace/report.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package namespace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/nirmata/kyverno/pkg/event"
|
||||
"github.com/nirmata/kyverno/pkg/info"
|
||||
"github.com/nirmata/kyverno/pkg/policyviolation"
|
||||
)
|
||||
|
||||
func (nsc *NamespaceController) report(policyInfos []info.PolicyInfo) {
|
||||
// generate events
|
||||
// generate policy violations
|
||||
for _, policyInfo := range policyInfos {
|
||||
// events
|
||||
// success - policy applied on resource
|
||||
// failure - policy/rule failed to apply on the resource
|
||||
reportEvents(policyInfo, nsc.eventGen)
|
||||
// policy violations
|
||||
// failure - policy/rule failed to apply on the resource
|
||||
}
|
||||
|
||||
// generate policy violation
|
||||
policyviolation.GeneratePolicyViolations(nsc.pvListerSynced, nsc.pvLister, nsc.kyvernoClient, policyInfos)
|
||||
|
||||
}
|
||||
|
||||
//reportEvents generates events for the failed resources
|
||||
func reportEvents(policyInfo info.PolicyInfo, eventGen event.Interface) {
|
||||
|
||||
if policyInfo.IsSuccessful() {
|
||||
return
|
||||
}
|
||||
glog.V(4).Infof("reporting results for policy %s application on resource %s/%s/%s", policyInfo.Name, policyInfo.RKind, policyInfo.RNamespace, policyInfo.RName)
|
||||
for _, rule := range policyInfo.Rules {
|
||||
if rule.IsSuccessful() {
|
||||
continue
|
||||
}
|
||||
|
||||
// generate event on resource for each failed rule
|
||||
e := &event.Info{}
|
||||
e.Kind = policyInfo.RKind
|
||||
e.Namespace = policyInfo.RNamespace
|
||||
e.Name = policyInfo.RName
|
||||
e.Reason = "Failure"
|
||||
e.Message = fmt.Sprintf("policy %s (%s) rule %s failed to apply. %v", policyInfo.Name, rule.RuleType.String(), rule.Name, rule.GetErrorString())
|
||||
eventGen.Add(e)
|
||||
|
||||
}
|
||||
// generate a event on policy for all failed rules
|
||||
e := &event.Info{}
|
||||
e.Kind = "Policy"
|
||||
e.Namespace = ""
|
||||
e.Name = policyInfo.Name
|
||||
e.Reason = "Failure"
|
||||
e.Message = fmt.Sprintf("failed to apply rules %s on resource %s/%s/%s", policyInfo.FailedRules(), policyInfo.RKind, policyInfo.RNamespace, policyInfo.RName)
|
||||
eventGen.Add(e)
|
||||
}
|
55
pkg/namespace/utils.go
Normal file
55
pkg/namespace/utils.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package namespace
|
||||
|
||||
const (
|
||||
wqNamespace string = "namespace"
|
||||
workerCount int = 1
|
||||
wqRetryLimit int = 5
|
||||
policyKind string = "Policy"
|
||||
)
|
||||
|
||||
// func namespaceMeetsRuleDescription(ns *corev1.Namespace, resourceDescription v1alpha1.ResourceDescription) bool {
|
||||
// //REWORK Not needed but verify the 'Namespace' is defined in the list of supported kinds
|
||||
// if !findKind(resourceDescription.Kinds, "Namespace") {
|
||||
// return false
|
||||
// }
|
||||
// if resourceDescription.Name != nil {
|
||||
// if !wildcard.Match(*resourceDescription.Name, ns.Name) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
|
||||
// if resourceDescription.Selector != nil {
|
||||
// selector, err := metav1.LabelSelectorAsSelector(resourceDescription.Selector)
|
||||
// if err != nil {
|
||||
// return false
|
||||
// }
|
||||
|
||||
// labelSet := convertLabelsToLabelSet(ns.Labels)
|
||||
// // labels
|
||||
// if !selector.Matches(labelSet) {
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
|
||||
// func convertLabelsToLabelSet(labelMap map[string]string) labels.Set {
|
||||
// labelSet := make(labels.Set, len(labelMap))
|
||||
// // REWORK: check if the below works
|
||||
// // if x, ok := labelMap.(labels.Set); !ok {
|
||||
|
||||
// // }
|
||||
// for k, v := range labelMap {
|
||||
// labelSet[k] = v
|
||||
// }
|
||||
// return labelSet
|
||||
// }
|
||||
|
||||
// func findKind(kinds []string, kindGVK string) bool {
|
||||
// for _, kind := range kinds {
|
||||
// if kind == kindGVK {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
|
@ -9,10 +9,10 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
"github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
informer "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/kyverno/v1alpha1"
|
||||
lister "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
"github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"github.com/nirmata/kyverno/pkg/event"
|
||||
"github.com/nirmata/kyverno/pkg/utils"
|
||||
|
@ -57,9 +57,9 @@ type PolicyController struct {
|
|||
// Policys that need to be synced
|
||||
queue workqueue.RateLimitingInterface
|
||||
// pLister can list/get policy from the shared informer's store
|
||||
pLister lister.PolicyLister
|
||||
pLister kyvernolister.PolicyLister
|
||||
// pvLister can list/get policy violation from the shared informer's store
|
||||
pvLister lister.PolicyViolationLister
|
||||
pvLister kyvernolister.PolicyViolationLister
|
||||
// pListerSynced returns true if the Policy store has been synced at least once
|
||||
pListerSynced cache.InformerSynced
|
||||
// pvListerSynced retrns true if the Policy store has been synced at least once
|
||||
|
@ -71,7 +71,7 @@ type PolicyController struct {
|
|||
}
|
||||
|
||||
// NewPolicyController create a new PolicyController
|
||||
func NewPolicyController(kyvernoClient *kyvernoclient.Clientset, client *client.Client, pInformer informer.PolicyInformer, pvInformer informer.PolicyViolationInformer, eventGen event.Interface) (*PolicyController, error) {
|
||||
func NewPolicyController(kyvernoClient *kyvernoclient.Clientset, client *client.Client, pInformer kyvernoinformer.PolicyInformer, pvInformer kyvernoinformer.PolicyViolationInformer, eventGen event.Interface) (*PolicyController, error) {
|
||||
// Event broad caster
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
|
@ -113,7 +113,8 @@ func NewPolicyController(kyvernoClient *kyvernoclient.Clientset, client *client.
|
|||
|
||||
// resource manager
|
||||
// rebuild after 300 seconds/ 5 mins
|
||||
pc.rm = NewResourceManager(300)
|
||||
//TODO: pass the time in seconds instead of converting it internally
|
||||
pc.rm = NewResourceManager(30)
|
||||
|
||||
return &pc, nil
|
||||
}
|
||||
|
@ -393,7 +394,6 @@ func (pc *PolicyController) syncPolicy(key string) error {
|
|||
// Deep-copy otherwise we are mutating our cache.
|
||||
// TODO: Deep-copy only when needed.
|
||||
p := policy.DeepCopy()
|
||||
// TODO: Update Status to update ObserverdGeneration
|
||||
|
||||
pvList, err := pc.getPolicyViolationsForPolicy(p)
|
||||
if err != nil {
|
||||
|
|
|
@ -64,16 +64,16 @@ func listResources(client *client.Client, policy kyverno.Policy, filterK8Resourc
|
|||
glog.V(4).Infof("skipping processing policy %s rule %s for kind Namespace", policy.Name, rule.Name)
|
||||
continue
|
||||
}
|
||||
//TODO: if namespace is not define can we default to *
|
||||
if rule.MatchResources.Namespace != "" {
|
||||
namespaces = append(namespaces, rule.MatchResources.Namespace)
|
||||
if len(rule.MatchResources.Namespaces) > 0 {
|
||||
namespaces = append(namespaces, rule.MatchResources.Namespaces...)
|
||||
glog.V(4).Infof("namespaces specified for inclusion: %v", rule.MatchResources.Namespaces)
|
||||
} else {
|
||||
glog.V(4).Infof("processing policy %s rule %s, namespace not defined, getting all namespaces ", policy.Name, rule.Name)
|
||||
// get all namespaces
|
||||
namespaces = getAllNamespaces(client)
|
||||
}
|
||||
// check if exclude namespace is not clashing
|
||||
namespaces = excludeNamespaces(namespaces, rule.ExcludeResources.Namespace)
|
||||
namespaces = excludeNamespaces(namespaces, rule.ExcludeResources.Namespaces)
|
||||
|
||||
// get resources in the namespaces
|
||||
for _, ns := range namespaces {
|
||||
|
@ -158,13 +158,13 @@ func kindIsExcluded(kind string, list []string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func excludeNamespaces(namespaces []string, excludeNs string) []string {
|
||||
if excludeNs == "" {
|
||||
func excludeNamespaces(namespaces, excludeNs []string) []string {
|
||||
if len(excludeNs) == 0 {
|
||||
return namespaces
|
||||
}
|
||||
filteredNamespaces := []string{}
|
||||
for _, n := range namespaces {
|
||||
if n == excludeNs {
|
||||
if utils.Contains(excludeNs, n) {
|
||||
continue
|
||||
}
|
||||
filteredNamespaces = append(filteredNamespaces, n)
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
"github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned/scheme"
|
||||
informer "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/kyverno/v1alpha1"
|
||||
lister "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
"github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
@ -47,9 +47,9 @@ type PolicyViolationController struct {
|
|||
// Policys that need to be synced
|
||||
queue workqueue.RateLimitingInterface
|
||||
// pvLister can list/get policy violation from the shared informer's store
|
||||
pvLister lister.PolicyViolationLister
|
||||
pvLister kyvernolister.PolicyViolationLister
|
||||
// pLister can list/get policy from the shared informer's store
|
||||
pLister lister.PolicyLister
|
||||
pLister kyvernolister.PolicyLister
|
||||
// pListerSynced returns true if the Policy store has been synced at least once
|
||||
pListerSynced cache.InformerSynced
|
||||
// pvListerSynced retrns true if the Policy store has been synced at least once
|
||||
|
@ -59,7 +59,7 @@ type PolicyViolationController struct {
|
|||
}
|
||||
|
||||
//NewPolicyViolationController creates a new NewPolicyViolationController
|
||||
func NewPolicyViolationController(client *client.Client, kyvernoClient *kyvernoclient.Clientset, pInformer informer.PolicyInformer, pvInformer informer.PolicyViolationInformer) (*PolicyViolationController, error) {
|
||||
func NewPolicyViolationController(client *client.Client, kyvernoClient *kyvernoclient.Clientset, pInformer kyvernoinformer.PolicyInformer, pvInformer kyvernoinformer.PolicyViolationInformer) (*PolicyViolationController, error) {
|
||||
// Event broad caster
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
|
@ -212,6 +212,7 @@ func (pvc *PolicyViolationController) syncPolicyViolation(key string) error {
|
|||
pv := policyViolation.DeepCopy()
|
||||
// TODO: Update Status to update ObserverdGeneration
|
||||
// TODO: check if the policy violation refers to a resource thats active ? // done by policy controller
|
||||
// TODO: remove the PV, if the corresponding policy is not present
|
||||
// TODO: additional check on deleted webhook for a resource, to delete a policy violation it has a policy violation
|
||||
// list the resource with label selectors, but this can be expensive for each delete request of a resource
|
||||
if err := pvc.syncActiveResource(pv); err != nil {
|
||||
|
@ -242,6 +243,8 @@ func (pvc *PolicyViolationController) syncActiveResource(curPv *kyverno.PolicyVi
|
|||
glog.V(4).Infof("error while retrieved resource %s/%s/%s: %v", rspec.Kind, rspec.Namespace, rspec.Name, err)
|
||||
return err
|
||||
}
|
||||
//TODO- if the policy is not present, remove the policy violation
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
lister "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
"github.com/nirmata/kyverno/pkg/info"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
@ -54,7 +54,7 @@ func buildPolicyViolationsForAPolicy(pi info.PolicyInfo) kyverno.PolicyViolation
|
|||
|
||||
//generatePolicyViolations generate policyViolation resources for the rules that failed
|
||||
//TODO: check if pvListerSynced is needed
|
||||
func GeneratePolicyViolations(pvListerSynced cache.InformerSynced, pvLister lister.PolicyViolationLister, client *kyvernoclient.Clientset, policyInfos []info.PolicyInfo) {
|
||||
func GeneratePolicyViolations(pvListerSynced cache.InformerSynced, pvLister kyvernolister.PolicyViolationLister, client *kyvernoclient.Clientset, policyInfos []info.PolicyInfo) {
|
||||
var pvs []kyverno.PolicyViolation
|
||||
for _, policyInfo := range policyInfos {
|
||||
if !policyInfo.IsSuccessful() {
|
||||
|
@ -100,7 +100,7 @@ func GeneratePolicyViolations(pvListerSynced cache.InformerSynced, pvLister list
|
|||
}
|
||||
|
||||
//TODO: change the name
|
||||
func getExistingPolicyViolationIfAny(pvListerSynced cache.InformerSynced, pvLister lister.PolicyViolationLister, newPv kyverno.PolicyViolation) (*kyverno.PolicyViolation, error) {
|
||||
func getExistingPolicyViolationIfAny(pvListerSynced cache.InformerSynced, pvLister kyvernolister.PolicyViolationLister, newPv kyverno.PolicyViolation) (*kyverno.PolicyViolation, error) {
|
||||
// TODO: check for existing ov using label selectors on resource and policy
|
||||
labelMap := map[string]string{"policy": newPv.Spec.Policy, "resource": newPv.Spec.ResourceSpec.ToKey()}
|
||||
ls := &metav1.LabelSelector{}
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
"k8s.io/api/admission/v1beta1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type K8Resource struct {
|
||||
|
@ -75,3 +77,12 @@ func ParseKinds(list string) []K8Resource {
|
|||
}
|
||||
return resources
|
||||
}
|
||||
|
||||
//NewKubeClient returns a new kubernetes client
|
||||
func NewKubeClient(config *rest.Config) (kubernetes.Interface, error) {
|
||||
kclient, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kclient, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
engine "github.com/nirmata/kyverno/pkg/engine"
|
||||
"github.com/nirmata/kyverno/pkg/info"
|
||||
"github.com/nirmata/kyverno/pkg/utils"
|
||||
v1beta1 "k8s.io/api/admission/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
@ -41,7 +42,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) (bool
|
|||
for _, policy := range policies {
|
||||
|
||||
// check if policy has a rule for the admission request kind
|
||||
if !StringInSlice(request.Kind.Kind, getApplicableKindsForPolicy(policy)) {
|
||||
if !utils.Contains(getApplicableKindsForPolicy(policy), request.Kind.Kind) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -344,11 +344,11 @@ func constructWebhook(name, servicePath string, caData []byte, validation bool,
|
|||
admregapi.Create,
|
||||
admregapi.Update,
|
||||
}
|
||||
// Add operation DELETE for validation
|
||||
if validation {
|
||||
operationtypes = append(operationtypes, admregapi.Delete)
|
||||
// // Add operation DELETE for validation
|
||||
// if validation {
|
||||
// operationtypes = append(operationtypes, admregapi.Delete)
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
return admregapi.Webhook{
|
||||
Name: name,
|
||||
|
@ -394,10 +394,10 @@ func constructDebugWebhook(name, url string, caData []byte, validation bool, tim
|
|||
admregapi.Create,
|
||||
admregapi.Update,
|
||||
}
|
||||
// Add operation DELETE for validation
|
||||
if validation {
|
||||
operationtypes = append(operationtypes, admregapi.Delete)
|
||||
}
|
||||
// // Add operation DELETE for validation
|
||||
// if validation {
|
||||
// operationtypes = append(operationtypes, admregapi.Delete)
|
||||
// }
|
||||
|
||||
return admregapi.Webhook{
|
||||
Name: name,
|
||||
|
|
|
@ -13,9 +13,9 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine"
|
||||
|
||||
"github.com/golang/glog"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/clientNew/clientset/versioned"
|
||||
informer "github.com/nirmata/kyverno/pkg/clientNew/informers/externalversions/kyverno/v1alpha1"
|
||||
lister "github.com/nirmata/kyverno/pkg/clientNew/listers/kyverno/v1alpha1"
|
||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
|
||||
lister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
|
||||
"github.com/nirmata/kyverno/pkg/config"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"github.com/nirmata/kyverno/pkg/event"
|
||||
|
@ -46,8 +46,8 @@ func NewWebhookServer(
|
|||
kyvernoClient *kyvernoclient.Clientset,
|
||||
client *client.Client,
|
||||
tlsPair *tlsutils.TlsPemPair,
|
||||
pInformer informer.PolicyInformer,
|
||||
pvInormer informer.PolicyViolationInformer,
|
||||
pInformer kyvernoinformer.PolicyInformer,
|
||||
pvInormer kyvernoinformer.PolicyViolationInformer,
|
||||
eventGen event.Interface,
|
||||
webhookRegistrationClient *WebhookRegistrationClient,
|
||||
filterK8Resources string) (*WebhookServer, error) {
|
||||
|
|
|
@ -26,16 +26,6 @@ func isAdmSuccesful(policyInfos []info.PolicyInfo) (bool, string) {
|
|||
return admSuccess, strings.Join(errMsgs, ";")
|
||||
}
|
||||
|
||||
//StringInSlice checks if string is present in slice of strings
|
||||
func StringInSlice(kind string, list []string) bool {
|
||||
for _, b := range list {
|
||||
if b == kind {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//ArrayFlags to store filterkinds
|
||||
type ArrayFlags []string
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
engine "github.com/nirmata/kyverno/pkg/engine"
|
||||
"github.com/nirmata/kyverno/pkg/info"
|
||||
"github.com/nirmata/kyverno/pkg/policyviolation"
|
||||
"github.com/nirmata/kyverno/pkg/utils"
|
||||
v1beta1 "k8s.io/api/admission/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -39,7 +40,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, res
|
|||
|
||||
for _, policy := range policies {
|
||||
|
||||
if !StringInSlice(request.Kind.Kind, getApplicableKindsForPolicy(policy)) {
|
||||
if !utils.Contains(getApplicableKindsForPolicy(policy), request.Kind.Kind) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux*) linkutil=readlink;;
|
||||
Darwin*) linkutil=greadlink;;
|
||||
*) machine="UNKNOWN:${unameOut}"
|
||||
esac
|
||||
|
||||
# get nirmata root
|
||||
NIRMATA_DIR=$(dirname ${BASH_SOURCE})/..
|
||||
NIRMATA_ROOT=$(${linkutil} -f ${NIRMATA_DIR})
|
||||
|
||||
# get relative path to code generation script
|
||||
CODEGEN_PKG=${NIRMATA_DIR}/vendor/k8s.io/code-generator
|
||||
|
||||
# get relative path of nirmata
|
||||
NIRMATA_PKG=${NIRMATA_ROOT#"${GOPATH}/src/"}
|
||||
|
||||
# perform code generation
|
||||
${CODEGEN_PKG}/generate-groups.sh \
|
||||
"deepcopy,client,informer,lister" \
|
||||
${NIRMATA_PKG}/pkg/clientNew \
|
||||
${NIRMATA_PKG}/pkg/api \
|
||||
kyverno:v1alpha1
|
|
@ -23,5 +23,5 @@ NIRMATA_PKG=${NIRMATA_ROOT#"${GOPATH}/src/"}
|
|||
${CODEGEN_PKG}/generate-groups.sh \
|
||||
"deepcopy,client,informer,lister" \
|
||||
${NIRMATA_PKG}/pkg/client \
|
||||
${NIRMATA_PKG}/pkg/apis \
|
||||
policy:v1alpha1
|
||||
${NIRMATA_PKG}/pkg/api \
|
||||
kyverno:v1alpha1
|
||||
|
|
Loading…
Add table
Reference in a new issue