mirror of
https://github.com/kyverno/kyverno.git
synced 2025-04-15 16:56:56 +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]
|
||||
}
|
||||
|
||||
glog.V(4).Infof("Loading variable serviceAccountName with value: %s", saName)
|
||||
saNameObj := struct {
|
||||
SA string `json:"serviceAccountName"`
|
||||
}{
|
||||
|
@ -137,7 +136,6 @@ func (ctx *Context) AddSA(userName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
glog.V(4).Infof("Loading variable serviceAccountNamespace with value: %s", saNamespace)
|
||||
saNsObj := struct {
|
||||
SA string `json:"serviceAccountNamespace"`
|
||||
}{
|
||||
|
|
|
@ -1,42 +1,24 @@
|
|||
package cleanup
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
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 {
|
||||
// 1-Corresponding policy has been deleted
|
||||
_, err := c.pLister.Get(gr.Spec.Policy)
|
||||
if errors.IsNotFound(err) {
|
||||
glog.V(4).Infof("delete GR %s", gr.Name)
|
||||
return c.control.Delete(gr.Name)
|
||||
}
|
||||
// 1- Corresponding policy has been deleted
|
||||
// then we dont delete the generated resources
|
||||
|
||||
// 2- Check for elapsed time since update
|
||||
if gr.Status.State == kyverno.Completed {
|
||||
glog.V(4).Infof("checking if owner exists for gr %s", gr.Name)
|
||||
if !ownerResourceExists(c.client, gr) {
|
||||
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)
|
||||
// 2- The trigger resource is deleted, then delete the generated resources
|
||||
if !ownerResourceExists(c.client, gr) {
|
||||
if err := deleteGeneratedResources(c.client, gr); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
createTime := gr.GetCreationTimestamp()
|
||||
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)
|
||||
// - trigger-resource is delted
|
||||
// - generated-resources are delted
|
||||
// - > Now delete the GenerateRequest CR
|
||||
return c.control.Delete(gr.Name)
|
||||
}
|
||||
return nil
|
||||
|
@ -44,16 +26,22 @@ func (c *Controller) processGR(gr kyverno.GenerateRequest) error {
|
|||
|
||||
func ownerResourceExists(client *dclient.Client, gr kyverno.GenerateRequest) bool {
|
||||
_, 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
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
func deleteGeneratedResources(client *dclient.Client, gr kyverno.GenerateRequest) error {
|
||||
for _, genResource := range gr.Status.GeneratedResources {
|
||||
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)
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -221,6 +221,11 @@ func applyRule(client *dclient.Client, rule kyverno.Rule, resource unstructured.
|
|||
newResource.SetName(gen.Name)
|
||||
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 {
|
||||
// Reset resource version
|
||||
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
|
||||
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
|
||||
// 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
|
||||
dataCopy, err := copyInterface(generateRule.Data)
|
||||
if err != nil {
|
||||
|
@ -414,26 +419,3 @@ func generatePV(gr kyverno.GenerateRequest, resource unstructured.Unstructured,
|
|||
}
|
||||
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