Skip to content

Commit 3909fcc

Browse files
authored
Merge pull request #3729 from jwcesign/cronhpa-imp
feat: Support CronFederatedHPA
2 parents b01cf50 + 068022d commit 3909fcc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+6731
-12
lines changed

artifacts/deploy/webhook-configuration.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,17 @@ webhooks:
209209
sideEffects: None
210210
admissionReviewVersions: [ "v1" ]
211211
timeoutSeconds: 10
212+
- name: cronfederatedhpa.karmada.io
213+
rules:
214+
- operations: ["CREATE", "UPDATE"]
215+
apiGroups: ["autoscaling.karmada.io"]
216+
apiVersions: ["*"]
217+
resources: ["cronfederatedhpas"]
218+
scope: "Namespaced"
219+
clientConfig:
220+
url: https://karmada-webhook.karmada-system.svc:443/validate-cronfederatedhpa
221+
caBundle: {{caBundle}}
222+
failurePolicy: Fail
223+
sideEffects: None
224+
admissionReviewVersions: [ "v1" ]
225+
timeoutSeconds: 10

cluster/images/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ FROM alpine:3.18.2
33
ARG BINARY
44

55
RUN apk add --no-cache ca-certificates
6+
#tzdata is used to parse the time zone information when using CronFederatedHPA
7+
RUN apk add --no-cache tzdata
68

79
COPY ${BINARY} /bin/${BINARY}

cluster/images/buildx.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ ARG BINARY
44
ARG TARGETPLATFORM
55

66
RUN apk add --no-cache ca-certificates
7+
#tzdata is used to parse the time zone information when using CronFederatedHPA
8+
RUN apk add --no-cache tzdata
79

810
COPY ${TARGETPLATFORM}/${BINARY} /bin/${BINARY}

cmd/controller-manager/app/controllermanager.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/karmada-io/karmada/pkg/controllers/binding"
3838
"github.com/karmada-io/karmada/pkg/controllers/cluster"
3939
controllerscontext "github.com/karmada-io/karmada/pkg/controllers/context"
40+
"github.com/karmada-io/karmada/pkg/controllers/cronfederatedhpa"
4041
"github.com/karmada-io/karmada/pkg/controllers/execution"
4142
"github.com/karmada-io/karmada/pkg/controllers/federatedhpa"
4243
metricsclient "github.com/karmada-io/karmada/pkg/controllers/federatedhpa/metrics"
@@ -204,6 +205,7 @@ func init() {
204205
controllers["gracefulEviction"] = startGracefulEvictionController
205206
controllers["applicationFailover"] = startApplicationFailoverController
206207
controllers["federatedHorizontalPodAutoscaler"] = startFederatedHorizontalPodAutoscalerController
208+
controllers["cronFederatedHorizontalPodAutoscaler"] = startCronFederatedHorizontalPodAutoscalerController
207209
}
208210

209211
func startClusterController(ctx controllerscontext.Context) (enabled bool, err error) {
@@ -591,6 +593,18 @@ func startFederatedHorizontalPodAutoscalerController(ctx controllerscontext.Cont
591593
return true, nil
592594
}
593595

596+
func startCronFederatedHorizontalPodAutoscalerController(ctx controllerscontext.Context) (enabled bool, err error) {
597+
cronFHPAController := cronfederatedhpa.CronFHPAController{
598+
Client: ctx.Mgr.GetClient(),
599+
EventRecorder: ctx.Mgr.GetEventRecorderFor(cronfederatedhpa.ControllerName),
600+
RateLimiterOptions: ctx.Opts.RateLimiterOptions,
601+
}
602+
if err = cronFHPAController.SetupWithManager(ctx.Mgr); err != nil {
603+
return false, err
604+
}
605+
return true, nil
606+
}
607+
594608
// setupControllers initialize controllers and setup one by one.
595609
func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stopChan <-chan struct{}) {
596610
restConfig := mgr.GetConfig()

cmd/webhook/app/webhook.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/karmada-io/karmada/pkg/webhook/clusteroverridepolicy"
2626
"github.com/karmada-io/karmada/pkg/webhook/clusterpropagationpolicy"
2727
"github.com/karmada-io/karmada/pkg/webhook/configuration"
28+
"github.com/karmada-io/karmada/pkg/webhook/cronfederatedhpa"
2829
"github.com/karmada-io/karmada/pkg/webhook/federatedhpa"
2930
"github.com/karmada-io/karmada/pkg/webhook/federatedresourcequota"
3031
"github.com/karmada-io/karmada/pkg/webhook/multiclusteringress"
@@ -129,6 +130,7 @@ func Run(ctx context.Context, opts *options.Options) error {
129130
hookServer.Register("/validate-resourceinterpreterwebhookconfiguration", &webhook.Admission{Handler: &configuration.ValidatingAdmission{}})
130131
hookServer.Register("/validate-federatedresourcequota", &webhook.Admission{Handler: &federatedresourcequota.ValidatingAdmission{}})
131132
hookServer.Register("/validate-federatedhpa", &webhook.Admission{Handler: &federatedhpa.ValidatingAdmission{}})
133+
hookServer.Register("/validate-cronfederatedhpa", &webhook.Admission{Handler: &cronfederatedhpa.ValidatingAdmission{}})
132134
hookServer.Register("/validate-resourceinterpretercustomization", &webhook.Admission{Handler: &resourceinterpretercustomization.ValidatingAdmission{Client: hookManager.GetClient()}})
133135
hookServer.Register("/validate-multiclusteringress", &webhook.Admission{Handler: &multiclusteringress.ValidatingAdmission{}})
134136
hookServer.Register("/mutate-federatedhpa", &webhook.Admission{Handler: &federatedhpa.MutatingAdmission{}})

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ module github.com/karmada-io/karmada
33
go 1.20
44

55
require (
6+
github.com/adhocore/gronx v1.6.3
67
github.com/distribution/distribution/v3 v3.0.0-20210507173845-9329f6a62b67
78
github.com/emirpasic/gods v1.18.1
89
github.com/evanphx/json-patch/v5 v5.6.0
10+
github.com/go-co-op/gocron v1.30.1
911
github.com/gogo/protobuf v1.3.2
1012
github.com/golang/mock v1.6.0
1113
github.com/google/go-cmp v0.5.9
@@ -133,7 +135,8 @@ require (
133135
github.com/prometheus/common v0.37.0 // indirect
134136
github.com/prometheus/procfs v0.8.0 // indirect
135137
github.com/rivo/uniseg v0.4.2 // indirect
136-
github.com/rogpeppe/go-internal v1.6.1 // indirect
138+
github.com/robfig/cron/v3 v3.0.1 // indirect
139+
github.com/rogpeppe/go-internal v1.8.1 // indirect
137140
github.com/rs/zerolog v1.26.1 // indirect
138141
github.com/russross/blackfriday/v2 v2.1.0 // indirect
139142
github.com/spf13/afero v1.9.3 // indirect

go.sum

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
8181
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
8282
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
8383
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
84+
github.com/adhocore/gronx v1.6.3 h1:bnm5vieTrY3QQPpsfB0hrAaeaHDpuZTUC2LLCVMLe9c=
85+
github.com/adhocore/gronx v1.6.3/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg=
8486
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
8587
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
8688
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -246,6 +248,8 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H
246248
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
247249
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
248250
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
251+
github.com/go-co-op/gocron v1.30.1 h1:tjWUvJl5KrcwpkEkSXFSQFr4F9h5SfV/m4+RX0cV2fs=
252+
github.com/go-co-op/gocron v1.30.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
249253
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
250254
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
251255
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -649,6 +653,7 @@ github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvI
649653
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
650654
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
651655
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
656+
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
652657
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
653658
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
654659
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -702,11 +707,14 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
702707
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
703708
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
704709
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
710+
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
711+
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
705712
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
706713
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
707714
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
708-
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
709715
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
716+
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
717+
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
710718
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
711719
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
712720
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=

pkg/apis/autoscaling/v1alpha1/well_known_constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package v1alpha1
22

33
const (
4+
// FederatedHPAKind is the kind of FederatedHPA in group autoscaling.karmada.io
5+
FederatedHPAKind = "FederatedHPA"
6+
47
// QuerySourceAnnotationKey is the annotation used in karmada-metrics-adapter to
58
// record the query source cluster
69
QuerySourceAnnotationKey = "resource.karmada.io/query-from-cluster"
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/*
2+
Copyright 2023 The Karmada Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package cronfederatedhpa
15+
16+
import (
17+
"context"
18+
19+
corev1 "k8s.io/api/core/v1"
20+
"k8s.io/apimachinery/pkg/api/equality"
21+
apierrors "k8s.io/apimachinery/pkg/api/errors"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/util/sets"
24+
"k8s.io/client-go/tools/record"
25+
"k8s.io/klog/v2"
26+
controllerruntime "sigs.k8s.io/controller-runtime"
27+
"sigs.k8s.io/controller-runtime/pkg/client"
28+
"sigs.k8s.io/controller-runtime/pkg/controller"
29+
30+
autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1"
31+
"github.com/karmada-io/karmada/pkg/sharedcli/ratelimiterflag"
32+
"github.com/karmada-io/karmada/pkg/util/helper"
33+
)
34+
35+
const (
36+
// ControllerName is the controller name that will be used when reporting events.
37+
ControllerName = "cronfederatedhpa-controller"
38+
)
39+
40+
// CronFHPAController is used to operate CronFederatedHPA.
41+
type CronFHPAController struct {
42+
client.Client // used to operate Cron resources.
43+
EventRecorder record.EventRecorder
44+
45+
RateLimiterOptions ratelimiterflag.Options
46+
CronHandler *CronHandler
47+
}
48+
49+
// Reconcile performs a full reconciliation for the object referred to by the Request.
50+
// The Controller will requeue the Request to be processed again if an error is non-nil or
51+
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
52+
func (c *CronFHPAController) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
53+
klog.V(4).Infof("Reconciling CronFederatedHPA %s", req.NamespacedName)
54+
55+
cronFHPA := &autoscalingv1alpha1.CronFederatedHPA{}
56+
if err := c.Client.Get(ctx, req.NamespacedName, cronFHPA); err != nil {
57+
if apierrors.IsNotFound(err) {
58+
klog.V(4).Infof("Begin to cleanup the cron jobs for CronFederatedHPA:%s", req.NamespacedName)
59+
c.CronHandler.StopCronFHPAExecutor(req.NamespacedName.String())
60+
return controllerruntime.Result{}, nil
61+
}
62+
63+
klog.Errorf("Fail to get CronFederatedHPA(%s):%v", req.NamespacedName, err)
64+
return controllerruntime.Result{Requeue: true}, err
65+
}
66+
67+
// If this CronFederatedHPA is deleting, stop all related cron executors
68+
if !cronFHPA.DeletionTimestamp.IsZero() {
69+
c.CronHandler.StopCronFHPAExecutor(req.NamespacedName.String())
70+
return controllerruntime.Result{}, nil
71+
}
72+
73+
origRuleSets := sets.New[string]()
74+
for _, history := range cronFHPA.Status.ExecutionHistories {
75+
origRuleSets.Insert(history.RuleName)
76+
}
77+
78+
// If scale target is updated, stop all the rule executors, and next steps will create the new executors
79+
if c.CronHandler.CronFHPAScaleTargetRefUpdates(req.NamespacedName.String(), cronFHPA.Spec.ScaleTargetRef) {
80+
c.CronHandler.StopCronFHPAExecutor(req.NamespacedName.String())
81+
}
82+
83+
c.CronHandler.AddCronExecutorIfNotExist(req.NamespacedName.String())
84+
85+
newRuleSets := sets.New[string]()
86+
for _, rule := range cronFHPA.Spec.Rules {
87+
if err := c.processCronRule(cronFHPA, rule); err != nil {
88+
return controllerruntime.Result{Requeue: true}, err
89+
}
90+
newRuleSets.Insert(rule.Name)
91+
}
92+
93+
// If rule is deleted, remove the rule executor from the handler
94+
for name := range origRuleSets {
95+
if newRuleSets.Has(name) {
96+
continue
97+
}
98+
c.CronHandler.StopRuleExecutor(req.NamespacedName.String(), name)
99+
if err := c.removeCronFHPAHistory(cronFHPA, name); err != nil {
100+
return controllerruntime.Result{Requeue: true}, err
101+
}
102+
}
103+
104+
return controllerruntime.Result{}, nil
105+
}
106+
107+
// SetupWithManager creates a controller and register to controller manager.
108+
func (c *CronFHPAController) SetupWithManager(mgr controllerruntime.Manager) error {
109+
c.CronHandler = NewCronHandler(mgr.GetClient(), mgr.GetEventRecorderFor(ControllerName))
110+
return controllerruntime.NewControllerManagedBy(mgr).
111+
For(&autoscalingv1alpha1.CronFederatedHPA{}).
112+
WithOptions(controller.Options{RateLimiter: ratelimiterflag.DefaultControllerRateLimiter(c.RateLimiterOptions)}).
113+
Complete(c)
114+
}
115+
116+
// processCronRule processes the cron rule
117+
func (c *CronFHPAController) processCronRule(cronFHPA *autoscalingv1alpha1.CronFederatedHPA, rule autoscalingv1alpha1.CronFederatedHPARule) error {
118+
cronFHPAKey := helper.GetCronFederatedHPAKey(cronFHPA)
119+
if ruleOld, exists := c.CronHandler.RuleCronExecutorExists(cronFHPAKey, rule.Name); exists {
120+
if equality.Semantic.DeepEqual(ruleOld, rule) {
121+
return nil
122+
}
123+
c.CronHandler.StopRuleExecutor(cronFHPAKey, rule.Name)
124+
}
125+
126+
if !helper.IsCronFederatedHPARuleSuspend(rule) {
127+
if err := c.CronHandler.CreateCronJobForExecutor(cronFHPA, rule); err != nil {
128+
c.EventRecorder.Event(cronFHPA, corev1.EventTypeWarning, "StartRuleFailed", err.Error())
129+
klog.Errorf("Fail to start cron for CronFederatedHPA(%s) rule(%s):%v", cronFHPAKey, rule.Name, err)
130+
return err
131+
}
132+
}
133+
134+
if err := c.updateRuleHistory(cronFHPA, rule); err != nil {
135+
c.EventRecorder.Event(cronFHPA, corev1.EventTypeWarning, "UpdateCronFederatedHPAFailed", err.Error())
136+
return err
137+
}
138+
return nil
139+
}
140+
141+
// updateRuleHistory updates the rule history
142+
func (c *CronFHPAController) updateRuleHistory(cronFHPA *autoscalingv1alpha1.CronFederatedHPA, rule autoscalingv1alpha1.CronFederatedHPARule) error {
143+
var nextExecutionTime *metav1.Time
144+
if !helper.IsCronFederatedHPARuleSuspend(rule) {
145+
// If rule is not suspended, we should set the nextExecutionTime filed, or the nextExecutionTime will be nil
146+
next, err := c.CronHandler.GetRuleNextExecuteTime(cronFHPA, rule.Name)
147+
if err != nil {
148+
klog.Errorf("Fail to get next execution time for CronFederatedHPA(%s/%s) rule(%s):%v",
149+
cronFHPA.Namespace, cronFHPA.Name, rule.Name, err)
150+
return err
151+
}
152+
nextExecutionTime = &metav1.Time{Time: next}
153+
}
154+
155+
exists := false
156+
for index, history := range cronFHPA.Status.ExecutionHistories {
157+
if history.RuleName != rule.Name {
158+
continue
159+
}
160+
exists = true
161+
cronFHPA.Status.ExecutionHistories[index].NextExecutionTime = nextExecutionTime
162+
break
163+
}
164+
165+
if !exists {
166+
ruleHistory := autoscalingv1alpha1.ExecutionHistory{
167+
RuleName: rule.Name,
168+
NextExecutionTime: nextExecutionTime,
169+
}
170+
cronFHPA.Status.ExecutionHistories = append(cronFHPA.Status.ExecutionHistories, ruleHistory)
171+
}
172+
173+
if err := c.Client.Status().Update(context.Background(), cronFHPA); err != nil {
174+
klog.Errorf("Fail to update CronFederatedHPA(%s/%s) rule(%s)'s next execution time:%v",
175+
cronFHPA.Namespace, cronFHPA.Name, err)
176+
return err
177+
}
178+
179+
return nil
180+
}
181+
182+
// removeCronFHPAHistory removes the rule history in status
183+
func (c *CronFHPAController) removeCronFHPAHistory(cronFHPA *autoscalingv1alpha1.CronFederatedHPA, ruleName string) error {
184+
exists := false
185+
for index, history := range cronFHPA.Status.ExecutionHistories {
186+
if history.RuleName != ruleName {
187+
continue
188+
}
189+
cronFHPA.Status.ExecutionHistories = append(cronFHPA.Status.ExecutionHistories[:index], cronFHPA.Status.ExecutionHistories[index+1:]...)
190+
exists = true
191+
break
192+
}
193+
194+
if !exists {
195+
return nil
196+
}
197+
if err := c.Client.Status().Update(context.Background(), cronFHPA); err != nil {
198+
c.EventRecorder.Event(cronFHPA, corev1.EventTypeWarning, "UpdateCronFederatedHPAFailed", err.Error())
199+
klog.Errorf("Fail to remove CronFederatedHPA(%s/%s) rule(%s) history:%v", cronFHPA.Namespace, cronFHPA.Name, ruleName, err)
200+
return err
201+
}
202+
203+
return nil
204+
}

0 commit comments

Comments
 (0)