diff --git a/definitions/install.yaml b/definitions/install.yaml index b16430045f..d2b2e6cb36 100644 --- a/definitions/install.yaml +++ b/definitions/install.yaml @@ -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: diff --git a/definitions/install_debug.yaml b/definitions/install_debug.yaml index 0d50728fdd..7a7cb7c95d 100644 --- a/definitions/install_debug.yaml +++ b/definitions/install_debug.yaml @@ -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: diff --git a/main.go b/main.go index 6446ea6d65..6db33a255e 100644 --- a/main.go +++ b/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() diff --git a/pkg/api/kyverno/v1alpha1/types.go b/pkg/api/kyverno/v1alpha1/types.go index 54a1f7f093..5597f97e23 100644 --- a/pkg/api/kyverno/v1alpha1/types.go +++ b/pkg/api/kyverno/v1alpha1/types.go @@ -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 diff --git a/pkg/api/kyverno/v1alpha1/zz_generated.deepcopy.go b/pkg/api/kyverno/v1alpha1/zz_generated.deepcopy.go index 16fa7b7f56..cfc34d4a24 100644 --- a/pkg/api/kyverno/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/api/kyverno/v1alpha1/zz_generated.deepcopy.go @@ -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) diff --git a/pkg/clientNew/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go similarity index 96% rename from pkg/clientNew/clientset/versioned/clientset.go rename to pkg/client/clientset/versioned/clientset.go index 8c98dcd7db..9725f2aae2 100644 --- a/pkg/clientNew/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -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" diff --git a/pkg/clientNew/clientset/versioned/doc.go b/pkg/client/clientset/versioned/doc.go similarity index 100% rename from pkg/clientNew/clientset/versioned/doc.go rename to pkg/client/clientset/versioned/doc.go diff --git a/pkg/clientNew/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go similarity index 89% rename from pkg/clientNew/clientset/versioned/fake/clientset_generated.go rename to pkg/client/clientset/versioned/fake/clientset_generated.go index 18e3e0d57b..ff0c5bc16f 100644 --- a/pkg/clientNew/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -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" diff --git a/pkg/clientNew/clientset/versioned/fake/doc.go b/pkg/client/clientset/versioned/fake/doc.go similarity index 100% rename from pkg/clientNew/clientset/versioned/fake/doc.go rename to pkg/client/clientset/versioned/fake/doc.go diff --git a/pkg/clientNew/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go similarity index 100% rename from pkg/clientNew/clientset/versioned/fake/register.go rename to pkg/client/clientset/versioned/fake/register.go diff --git a/pkg/clientNew/clientset/versioned/scheme/doc.go b/pkg/client/clientset/versioned/scheme/doc.go similarity index 100% rename from pkg/clientNew/clientset/versioned/scheme/doc.go rename to pkg/client/clientset/versioned/scheme/doc.go diff --git a/pkg/clientNew/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go similarity index 100% rename from pkg/clientNew/clientset/versioned/scheme/register.go rename to pkg/client/clientset/versioned/scheme/register.go diff --git a/pkg/clientNew/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go similarity index 95% rename from pkg/clientNew/informers/externalversions/factory.go rename to pkg/client/informers/externalversions/factory.go index 07bddb9a53..e2da4e38ee 100644 --- a/pkg/clientNew/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -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" diff --git a/pkg/clientNew/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go similarity index 100% rename from pkg/clientNew/informers/externalversions/generic.go rename to pkg/client/informers/externalversions/generic.go diff --git a/pkg/clientNew/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go similarity index 94% rename from pkg/clientNew/informers/externalversions/internalinterfaces/factory_interfaces.go rename to pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go index 2081ff4851..65a1d1de8f 100644 --- a/pkg/clientNew/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -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" diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/doc.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/doc.go deleted file mode 100644 index df51baa4d4..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/doc.go +++ /dev/null @@ -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 diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go deleted file mode 100644 index 16f4439906..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go +++ /dev/null @@ -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 diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go deleted file mode 100644 index 244260245f..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_policy.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_policy.go deleted file mode 100644 index 76bd94b95f..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_policy.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_policyviolation.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_policyviolation.go deleted file mode 100644 index e5306f11fe..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_policyviolation.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go deleted file mode 100644 index 442fa55942..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go +++ /dev/null @@ -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{} diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go deleted file mode 100644 index 93b837d4df..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/policy.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/policy.go deleted file mode 100644 index b7fb02600e..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/policy.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/policyviolation.go b/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/policyviolation.go deleted file mode 100644 index bc93b28281..0000000000 --- a/pkg/clientNew/clientset/versioned/typed/kyverno/v1alpha1/policyviolation.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/informers/externalversions/kyverno/interface.go b/pkg/clientNew/informers/externalversions/kyverno/interface.go deleted file mode 100644 index ee3f322230..0000000000 --- a/pkg/clientNew/informers/externalversions/kyverno/interface.go +++ /dev/null @@ -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) -} diff --git a/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/interface.go b/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/interface.go deleted file mode 100644 index ceead2b318..0000000000 --- a/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/interface.go +++ /dev/null @@ -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} -} diff --git a/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/policy.go b/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/policy.go deleted file mode 100644 index b59ee59a86..0000000000 --- a/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/policy.go +++ /dev/null @@ -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()) -} diff --git a/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/policyviolation.go b/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/policyviolation.go deleted file mode 100644 index 286b015fd9..0000000000 --- a/pkg/clientNew/informers/externalversions/kyverno/v1alpha1/policyviolation.go +++ /dev/null @@ -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()) -} diff --git a/pkg/clientNew/listers/kyverno/v1alpha1/expansion_generated.go b/pkg/clientNew/listers/kyverno/v1alpha1/expansion_generated.go deleted file mode 100644 index bfe398f1be..0000000000 --- a/pkg/clientNew/listers/kyverno/v1alpha1/expansion_generated.go +++ /dev/null @@ -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 - -} diff --git a/pkg/clientNew/listers/kyverno/v1alpha1/policy.go b/pkg/clientNew/listers/kyverno/v1alpha1/policy.go deleted file mode 100644 index c981855c33..0000000000 --- a/pkg/clientNew/listers/kyverno/v1alpha1/policy.go +++ /dev/null @@ -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 -} diff --git a/pkg/clientNew/listers/kyverno/v1alpha1/policyviolation.go b/pkg/clientNew/listers/kyverno/v1alpha1/policyviolation.go deleted file mode 100644 index e93ec95228..0000000000 --- a/pkg/clientNew/listers/kyverno/v1alpha1/policyviolation.go +++ /dev/null @@ -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 -} diff --git a/pkg/engine/generation.go b/pkg/engine/generation.go index a63968b1ca..d41380edcb 100644 --- a/pkg/engine/generation.go +++ b/pkg/engine/generation.go @@ -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{} diff --git a/pkg/engine/overlay.go b/pkg/engine/overlay.go index 4757ad3ca1..f71732e78c 100644 --- a/pkg/engine/overlay.go +++ b/pkg/engine/overlay.go @@ -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 diff --git a/pkg/engine/overlayPatch.go b/pkg/engine/overlayPatch.go index d71896b5c7..9f4df0ce90 100644 --- a/pkg/engine/overlayPatch.go +++ b/pkg/engine/overlayPatch.go @@ -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") { diff --git a/pkg/engine/utils.go b/pkg/engine/utils.go index d555972d96..9096a74869 100644 --- a/pkg/engine/utils.go +++ b/pkg/engine/utils.go @@ -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{}) diff --git a/pkg/engine/utils_test.go b/pkg/engine/utils_test.go index ad996c10f8..81379246c5 100644 --- a/pkg/engine/utils_test.go +++ b/pkg/engine/utils_test.go @@ -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)" diff --git a/pkg/event/controller.go b/pkg/event/controller.go index 0ec2ca83da..bd8850388a 100644 --- a/pkg/event/controller.go +++ b/pkg/event/controller.go @@ -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 diff --git a/pkg/gencontroller/utils.go b/pkg/gencontroller/utils.go deleted file mode 100644 index 609d53f917..0000000000 --- a/pkg/gencontroller/utils.go +++ /dev/null @@ -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 -} diff --git a/pkg/namespace/controller.go b/pkg/namespace/controller.go new file mode 100644 index 0000000000..78e6340a3f --- /dev/null +++ b/pkg/namespace/controller.go @@ -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 +} diff --git a/pkg/namespace/expansion.go b/pkg/namespace/expansion.go new file mode 100644 index 0000000000..1e256e556e --- /dev/null +++ b/pkg/namespace/expansion.go @@ -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 +} diff --git a/pkg/namespace/generation.go b/pkg/namespace/generation.go new file mode 100644 index 0000000000..18a6a2908d --- /dev/null +++ b/pkg/namespace/generation.go @@ -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 +} diff --git a/pkg/namespace/report.go b/pkg/namespace/report.go new file mode 100644 index 0000000000..57306c289c --- /dev/null +++ b/pkg/namespace/report.go @@ -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) +} diff --git a/pkg/namespace/utils.go b/pkg/namespace/utils.go new file mode 100644 index 0000000000..ee0922fc44 --- /dev/null +++ b/pkg/namespace/utils.go @@ -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 +// } diff --git a/pkg/policy/controller.go b/pkg/policy/controller.go index f756c5a999..142f28594f 100644 --- a/pkg/policy/controller.go +++ b/pkg/policy/controller.go @@ -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 { diff --git a/pkg/policy/existing.go b/pkg/policy/existing.go index b61ec78fd5..eaa5d0657d 100644 --- a/pkg/policy/existing.go +++ b/pkg/policy/existing.go @@ -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) diff --git a/pkg/policyviolation/controller.go b/pkg/policyviolation/controller.go index 0c1ff50741..045f59b857 100644 --- a/pkg/policyviolation/controller.go +++ b/pkg/policyviolation/controller.go @@ -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 } diff --git a/pkg/policyviolation/helpers.go b/pkg/policyviolation/helpers.go index ae62e87b5a..98ab01c0a9 100644 --- a/pkg/policyviolation/helpers.go +++ b/pkg/policyviolation/helpers.go @@ -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{} diff --git a/pkg/utils/util.go b/pkg/utils/util.go index 2b6d4a90e6..e77e1a55db 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -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 +} diff --git a/pkg/webhooks/mutation.go b/pkg/webhooks/mutation.go index 88c60afa4a..d1e9247af6 100644 --- a/pkg/webhooks/mutation.go +++ b/pkg/webhooks/mutation.go @@ -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 } diff --git a/pkg/webhooks/registration.go b/pkg/webhooks/registration.go index 739c64392e..99c2638148 100644 --- a/pkg/webhooks/registration.go +++ b/pkg/webhooks/registration.go @@ -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, diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 9d3131b561..16d3d19a15 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -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) { diff --git a/pkg/webhooks/utils.go b/pkg/webhooks/utils.go index 37713d16d5..f522a135f2 100644 --- a/pkg/webhooks/utils.go +++ b/pkg/webhooks/utils.go @@ -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 diff --git a/pkg/webhooks/validation.go b/pkg/webhooks/validation.go index 56aa4d1970..6e2953b324 100644 --- a/pkg/webhooks/validation.go +++ b/pkg/webhooks/validation.go @@ -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 } diff --git a/scripts/new_update-codegen.sh b/scripts/new_update-codegen.sh deleted file mode 100755 index 38f54515e6..0000000000 --- a/scripts/new_update-codegen.sh +++ /dev/null @@ -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 diff --git a/scripts/update-codegen.sh b/scripts/update-codegen.sh index fd53c78cb5..b339547fa8 100755 --- a/scripts/update-codegen.sh +++ b/scripts/update-codegen.sh @@ -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