1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

refactor: get the last execution time from the cleanup policy interface (#8531) (#8541)

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
gcp-cherry-pick-bot[bot] 2023-09-27 07:29:39 +00:00 committed by GitHub
parent a9f93134d5
commit febc017b52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 30 deletions

View file

@ -1,6 +1,8 @@
package v2alpha1 package v2alpha1
import ( import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
@ -13,6 +15,8 @@ type CleanupPolicyInterface interface {
IsNamespaced() bool IsNamespaced() bool
GetSpec() *CleanupPolicySpec GetSpec() *CleanupPolicySpec
GetStatus() *CleanupPolicyStatus GetStatus() *CleanupPolicyStatus
GetExecutionTime() (*time.Time, error)
GetNextExecutionTime(time.Time) (*time.Time, error)
Validate(sets.Set[string]) field.ErrorList Validate(sets.Set[string]) field.ErrorList
GetKind() string GetKind() string
GetAPIVersion() string GetAPIVersion() string

View file

@ -17,6 +17,9 @@ limitations under the License.
package v2alpha1 package v2alpha1
import ( import (
"time"
"github.com/aptible/supercronic/cronexpr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1" kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1"
datautils "github.com/kyverno/kyverno/pkg/utils/data" datautils "github.com/kyverno/kyverno/pkg/utils/data"
@ -58,6 +61,27 @@ func (p *CleanupPolicy) GetStatus() *CleanupPolicyStatus {
return &p.Status return &p.Status
} }
// GetExecutionTime returns the execution time of the policy
func (p *CleanupPolicy) GetExecutionTime() (*time.Time, error) {
lastExecutionTime := p.Status.LastExecutionTime.Time
if lastExecutionTime.IsZero() {
creationTime := p.GetCreationTimestamp().Time
return p.GetNextExecutionTime(creationTime)
} else {
return p.GetNextExecutionTime(lastExecutionTime)
}
}
// GetNextExecutionTime returns the next execution time of the policy
func (p *CleanupPolicy) GetNextExecutionTime(time time.Time) (*time.Time, error) {
cronExpr, err := cronexpr.Parse(p.Spec.Schedule)
if err != nil {
return nil, err
}
nextExecutionTime := cronExpr.Next(time)
return &nextExecutionTime, nil
}
// Validate implements programmatic validation // Validate implements programmatic validation
func (p *CleanupPolicy) Validate(clusterResources sets.Set[string]) (errs field.ErrorList) { func (p *CleanupPolicy) Validate(clusterResources sets.Set[string]) (errs field.ErrorList) {
errs = append(errs, kyvernov1.ValidatePolicyName(field.NewPath("metadata").Child("name"), p.Name)...) errs = append(errs, kyvernov1.ValidatePolicyName(field.NewPath("metadata").Child("name"), p.Name)...)
@ -123,6 +147,27 @@ func (p *ClusterCleanupPolicy) GetStatus() *CleanupPolicyStatus {
return &p.Status return &p.Status
} }
// GetExecutionTime returns the execution time of the policy
func (p *ClusterCleanupPolicy) GetExecutionTime() (*time.Time, error) {
lastExecutionTime := p.Status.LastExecutionTime.Time
if lastExecutionTime.IsZero() {
creationTime := p.GetCreationTimestamp().Time
return p.GetNextExecutionTime(creationTime)
} else {
return p.GetNextExecutionTime(lastExecutionTime)
}
}
// GetNextExecutionTime returns the next execution time of the policy
func (p *ClusterCleanupPolicy) GetNextExecutionTime(time time.Time) (*time.Time, error) {
cronExpr, err := cronexpr.Parse(p.Spec.Schedule)
if err != nil {
return nil, err
}
nextExecutionTime := cronExpr.Next(time)
return &nextExecutionTime, nil
}
// GetKind returns the resource kind // GetKind returns the resource kind
func (p *ClusterCleanupPolicy) GetKind() string { func (p *ClusterCleanupPolicy) GetKind() string {
return p.Kind return p.Kind

View file

@ -4,7 +4,6 @@ import (
"context" "context"
"time" "time"
"github.com/aptible/supercronic/cronexpr"
"github.com/go-logr/logr" "github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
@ -327,44 +326,31 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
logger.Error(err, "unable to get the policy from policy informer") logger.Error(err, "unable to get the policy from policy informer")
return err return err
} }
spec := policy.GetSpec()
cronExpr, err := cronexpr.Parse(spec.Schedule) var nextExecutionTime *time.Time
executionTime, err := policy.GetExecutionTime()
if err != nil { if err != nil {
logger.Error(err, "unable to parse the schedule") logger.Error(err, "failed to get the policy execution time")
return err return err
} }
status := policy.GetStatus()
creationTime := policy.GetCreationTimestamp().Time
firstExecutionTime := cronExpr.Next(creationTime)
var nextExecutionTime time.Time
// In case it isn't the first execution of the cleanup policy.
if firstExecutionTime.Before(time.Now()) {
var executionTime time.Time
if status.LastExecutionTime.IsZero() {
executionTime = firstExecutionTime
} else {
executionTime = cronExpr.Next(status.LastExecutionTime.Time)
}
// In case it is the time to do the cleanup process // In case it is the time to do the cleanup process
if time.Now().After(executionTime) { if time.Now().After(*executionTime) {
err := c.cleanup(ctx, logger, policy) err := c.cleanup(ctx, logger, policy)
if err != nil { if err != nil {
return err return err
} }
c.updateCleanupPolicyStatus(ctx, policy, namespace, executionTime) c.updateCleanupPolicyStatus(ctx, policy, namespace, *executionTime)
nextExecutionTime = cronExpr.Next(executionTime) nextExecutionTime, err = policy.GetNextExecutionTime(*executionTime)
if err != nil {
logger.Error(err, "failed to get the policy next execution time")
return err
}
} else { } else {
nextExecutionTime = executionTime nextExecutionTime = executionTime
} }
} else {
// In case it is the first execution of the cleanup policy.
nextExecutionTime = firstExecutionTime
}
// calculate the remaining time until deletion. // calculate the remaining time until deletion.
timeRemaining := time.Until(nextExecutionTime) timeRemaining := time.Until(*nextExecutionTime)
// add the item back to the queue after the remaining time. // add the item back to the queue after the remaining time.
c.queue.AddAfter(key, timeRemaining) c.queue.AddAfter(key, timeRemaining)
return nil return nil