mirror of
https://github.com/kyverno/kyverno.git
synced 2025-04-16 01:07:14 +00:00
generate rule processing refactoring
This commit is contained in:
parent
0518aebb29
commit
34ad3a9a2b
4 changed files with 81 additions and 56 deletions
|
@ -122,7 +122,6 @@ func (ctx *Context) AddSA(userName string) error {
|
||||||
saNamespace = groups[0]
|
saNamespace = groups[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(4).Infof("Loading variable serviceAccountName with value: %s", saName)
|
|
||||||
saNameObj := struct {
|
saNameObj := struct {
|
||||||
SA string `json:"serviceAccountName"`
|
SA string `json:"serviceAccountName"`
|
||||||
}{
|
}{
|
||||||
|
@ -137,7 +136,6 @@ func (ctx *Context) AddSA(userName string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(4).Infof("Loading variable serviceAccountNamespace with value: %s", saNamespace)
|
|
||||||
saNsObj := struct {
|
saNsObj := struct {
|
||||||
SA string `json:"serviceAccountNamespace"`
|
SA string `json:"serviceAccountNamespace"`
|
||||||
}{
|
}{
|
||||||
|
|
|
@ -1,42 +1,24 @@
|
||||||
package cleanup
|
package cleanup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||||
dclient "github.com/nirmata/kyverno/pkg/dclient"
|
dclient "github.com/nirmata/kyverno/pkg/dclient"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const timoutMins = 2
|
|
||||||
const timeout = time.Minute * timoutMins // 2 minutes
|
|
||||||
|
|
||||||
func (c *Controller) processGR(gr kyverno.GenerateRequest) error {
|
func (c *Controller) processGR(gr kyverno.GenerateRequest) error {
|
||||||
// 1-Corresponding policy has been deleted
|
// 1- Corresponding policy has been deleted
|
||||||
_, err := c.pLister.Get(gr.Spec.Policy)
|
// then we dont delete the generated resources
|
||||||
if errors.IsNotFound(err) {
|
|
||||||
glog.V(4).Infof("delete GR %s", gr.Name)
|
|
||||||
return c.control.Delete(gr.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2- Check for elapsed time since update
|
// 2- The trigger resource is deleted, then delete the generated resources
|
||||||
if gr.Status.State == kyverno.Completed {
|
if !ownerResourceExists(c.client, gr) {
|
||||||
glog.V(4).Infof("checking if owner exists for gr %s", gr.Name)
|
if err := deleteGeneratedResources(c.client, gr); err != nil {
|
||||||
if !ownerResourceExists(c.client, gr) {
|
return err
|
||||||
if err := deleteGeneratedResources(c.client, gr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
glog.V(4).Infof("delete GR %s", gr.Name)
|
|
||||||
return c.control.Delete(gr.Name)
|
|
||||||
}
|
}
|
||||||
return nil
|
// - trigger-resource is delted
|
||||||
}
|
// - generated-resources are delted
|
||||||
createTime := gr.GetCreationTimestamp()
|
// - > Now delete the GenerateRequest CR
|
||||||
if time.Since(createTime.UTC()) > timeout {
|
|
||||||
// the GR was in state ["",Failed] for more than timeout
|
|
||||||
glog.V(4).Infof("GR %s was not processed successfully in %d minutes", gr.Name, timoutMins)
|
|
||||||
glog.V(4).Infof("delete GR %s", gr.Name)
|
|
||||||
return c.control.Delete(gr.Name)
|
return c.control.Delete(gr.Name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -44,16 +26,22 @@ func (c *Controller) processGR(gr kyverno.GenerateRequest) error {
|
||||||
|
|
||||||
func ownerResourceExists(client *dclient.Client, gr kyverno.GenerateRequest) bool {
|
func ownerResourceExists(client *dclient.Client, gr kyverno.GenerateRequest) bool {
|
||||||
_, err := client.GetResource(gr.Spec.Resource.Kind, gr.Spec.Resource.Namespace, gr.Spec.Resource.Name)
|
_, err := client.GetResource(gr.Spec.Resource.Kind, gr.Spec.Resource.Namespace, gr.Spec.Resource.Name)
|
||||||
if err != nil {
|
// trigger resources has been deleted
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
glog.V(4).Infof("Failed to get resource %s/%s/%s: error : %s", gr.Spec.Resource.Kind, gr.Spec.Resource.Namespace, gr.Spec.Resource.Name, err)
|
||||||
|
}
|
||||||
|
// if there was an error while querying the resources we dont delete the generated resources
|
||||||
|
// but expect the deletion in next reconciliation loop
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteGeneratedResources(client *dclient.Client, gr kyverno.GenerateRequest) error {
|
func deleteGeneratedResources(client *dclient.Client, gr kyverno.GenerateRequest) error {
|
||||||
for _, genResource := range gr.Status.GeneratedResources {
|
for _, genResource := range gr.Status.GeneratedResources {
|
||||||
err := client.DeleteResource(genResource.Kind, genResource.Namespace, genResource.Name, false)
|
err := client.DeleteResource(genResource.Kind, genResource.Namespace, genResource.Name, false)
|
||||||
if errors.IsNotFound(err) {
|
if apierrors.IsNotFound(err) {
|
||||||
glog.V(4).Infof("resource %s/%s/%s not found, will no delete", genResource.Kind, genResource.Namespace, genResource.Name)
|
glog.V(4).Infof("resource %s/%s/%s not found, will no delete", genResource.Kind, genResource.Namespace, genResource.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,11 @@ func applyRule(client *dclient.Client, rule kyverno.Rule, resource unstructured.
|
||||||
newResource.SetName(gen.Name)
|
newResource.SetName(gen.Name)
|
||||||
newResource.SetNamespace(gen.Namespace)
|
newResource.SetNamespace(gen.Namespace)
|
||||||
|
|
||||||
|
// manage labels
|
||||||
|
// - app.kubernetes.io/managed-by: kyverno
|
||||||
|
// - kyverno.io/generated-by: kind/namespace/name (trigger resource)
|
||||||
|
manageLabels(newResource, resource)
|
||||||
|
|
||||||
if mode == Create {
|
if mode == Create {
|
||||||
// Reset resource version
|
// Reset resource version
|
||||||
newResource.SetResourceVersion("")
|
newResource.SetResourceVersion("")
|
||||||
|
@ -308,7 +313,7 @@ func copyInterface(original interface{}) (interface{}, error) {
|
||||||
// manage the creation/update of resource to be generated using the spec defined in the policy
|
// manage the creation/update of resource to be generated using the spec defined in the policy
|
||||||
func handleData(ruleName string, generateRule kyverno.Generation, client *dclient.Client, resource unstructured.Unstructured, ctx context.EvalInterface) (map[string]interface{}, ResourceMode, error) {
|
func handleData(ruleName string, generateRule kyverno.Generation, client *dclient.Client, resource unstructured.Unstructured, ctx context.EvalInterface) (map[string]interface{}, ResourceMode, error) {
|
||||||
//work on copy of the data
|
//work on copy of the data
|
||||||
// as the type of data stoed in interface is not know,
|
// as the type of data stored in interface is not know,
|
||||||
// we marshall the data and unmarshal it into a new resource to create a copy
|
// we marshall the data and unmarshal it into a new resource to create a copy
|
||||||
dataCopy, err := copyInterface(generateRule.Data)
|
dataCopy, err := copyInterface(generateRule.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -414,26 +419,3 @@ func generatePV(gr kyverno.GenerateRequest, resource unstructured.Unstructured,
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func addLabels(unstr *unstructured.Unstructured) {
|
|
||||||
// add managedBY label if not defined
|
|
||||||
labels := unstr.GetLabels()
|
|
||||||
if labels == nil {
|
|
||||||
labels = map[string]string{}
|
|
||||||
}
|
|
||||||
// ManagedBy label
|
|
||||||
key := "app.kubernetes.io/managed-by"
|
|
||||||
value := "kyverno"
|
|
||||||
val, ok := labels[key]
|
|
||||||
if ok {
|
|
||||||
if val != value {
|
|
||||||
glog.Infof("resource managed by %s, kyverno wont over-ride the label", val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// we dont over-ride the key managed by
|
|
||||||
if !ok {
|
|
||||||
// add lable
|
|
||||||
labels[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
57
pkg/generate/labels.go
Normal file
57
pkg/generate/labels.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
)
|
||||||
|
|
||||||
|
func manageLabels(unstr *unstructured.Unstructured, triggerResource unstructured.Unstructured) {
|
||||||
|
// add managedBY label if not defined
|
||||||
|
labels := unstr.GetLabels()
|
||||||
|
if labels == nil {
|
||||||
|
labels = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle managedBy label
|
||||||
|
managedBy(labels)
|
||||||
|
// handle generatedBy label
|
||||||
|
generatedBy(labels, triggerResource)
|
||||||
|
|
||||||
|
// update the labels
|
||||||
|
unstr.SetLabels(labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
func managedBy(labels map[string]string) {
|
||||||
|
// ManagedBy label
|
||||||
|
key := "app.kubernetes.io/managed-by"
|
||||||
|
value := "kyverno"
|
||||||
|
val, ok := labels[key]
|
||||||
|
if ok {
|
||||||
|
if val != value {
|
||||||
|
glog.Infof("resource managed by %s, kyverno wont over-ride the label", val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
// add label
|
||||||
|
labels[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatedBy(labels map[string]string, triggerResource unstructured.Unstructured) {
|
||||||
|
key := "kyverno.io/generated-by"
|
||||||
|
value := fmt.Sprintf("%s-%s-%s", triggerResource.GetKind(), triggerResource.GetNamespace(), triggerResource.GetName())
|
||||||
|
val, ok := labels[key]
|
||||||
|
if ok {
|
||||||
|
if val != value {
|
||||||
|
glog.Infof("resource generated by %s, kyverno wont over-ride the label", val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
// add label
|
||||||
|
labels[key] = value
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue