diff --git a/pkg/engine/context/context.go b/pkg/engine/context/context.go index 81d174f2cd..09fcc30d86 100644 --- a/pkg/engine/context/context.go +++ b/pkg/engine/context/context.go @@ -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"` }{ diff --git a/pkg/generate/cleanup/cleanup.go b/pkg/generate/cleanup/cleanup.go index 7edc7a3cbc..878c4be589 100644 --- a/pkg/generate/cleanup/cleanup.go +++ b/pkg/generate/cleanup/cleanup.go @@ -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 } diff --git a/pkg/generate/generate.go b/pkg/generate/generate.go index dac8632f89..9fc5de7835 100644 --- a/pkg/generate/generate.go +++ b/pkg/generate/generate.go @@ -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 - } - -} diff --git a/pkg/generate/labels.go b/pkg/generate/labels.go new file mode 100644 index 0000000000..282caf55fa --- /dev/null +++ b/pkg/generate/labels.go @@ -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 + } +}