Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paused ScaledObject continues after removing pause annotation #4734

Merged
merged 3 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio

### Fixes

- TODO ([#XXX](https://github.com/kedacore/keda/issue/XXX))
- **General**: Paused ScaledObject continues working after removing the annotation ([#4733](https://github.com/kedacore/keda/issues/4733))

### Deprecations

Expand Down
20 changes: 12 additions & 8 deletions controllers/keda/util/predicate.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ func (PausedReplicasPredicate) Update(e event.UpdateEvent) bool {

newAnnotations := e.ObjectNew.GetAnnotations()
oldAnnotations := e.ObjectOld.GetAnnotations()
if newAnnotations != nil && oldAnnotations != nil {
if newVal, ok1 := newAnnotations[PausedReplicasAnnotation]; ok1 {
if oldVal, ok2 := oldAnnotations[PausedReplicasAnnotation]; ok2 {
return newVal != oldVal
}
return true
}

newPausedValue := ""
oldPausedValue := ""

if newAnnotations != nil {
newPausedValue = newAnnotations[PausedReplicasAnnotation]
}
return false

if oldAnnotations != nil {
oldPausedValue = oldAnnotations[PausedReplicasAnnotation]
}

return newPausedValue != oldPausedValue
}

type ScaleObjectReadyConditionPredicate struct {
Expand Down
52 changes: 17 additions & 35 deletions tests/internals/pause_scaledobject/pause_scaledobject_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ type templateData struct {
DeploymentName string
ScaledObjectName string
MonitoredDeploymentName string
PausedReplicaCount int
CooldownPeriod int
}

const (
Expand Down Expand Up @@ -99,29 +97,7 @@ spec:
pollingInterval: 5
minReplicaCount: 0
maxReplicaCount: 1
cooldownPeriod: {{.CooldownPeriod}}
triggers:
- type: kubernetes-workload
metadata:
podSelector: 'app={{.MonitoredDeploymentName}}'
value: '1'
`

scaledObjectAnnotatedTemplate = `
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: {{.ScaledObjectName}}
namespace: {{.TestNamespace}}
annotations:
autoscaling.keda.sh/paused-replicas: "{{.PausedReplicaCount}}"
spec:
scaleTargetRef:
name: {{.DeploymentName}}
pollingInterval: 5
minReplicaCount: 0
maxReplicaCount: 1
cooldownPeriod: {{.CooldownPeriod}}
cooldownPeriod: 5
triggers:
- type: kubernetes-workload
metadata:
Expand Down Expand Up @@ -160,17 +136,27 @@ func getTemplateData() (templateData, []Template) {
DeploymentName: deploymentName,
ScaledObjectName: scaledObjectName,
MonitoredDeploymentName: monitoredDeploymentName,
PausedReplicaCount: 0,
CooldownPeriod: 10,
}, []Template{
{Name: "deploymentTemplate", Config: deploymentTemplate},
{Name: "monitoredDeploymentTemplate", Config: monitoredDeploymentTemplate},
{Name: "scaledObjectAnnotatedTemplate", Config: scaledObjectAnnotatedTemplate},
{Name: "scaledObjectAnnotatedTemplate", Config: scaledObjectTemplate},
}
}

func upsertScaledObjectAnnotation(t assert.TestingT, value int) {
_, err := ExecuteCommand(fmt.Sprintf("kubectl annotate scaledobject/%s -n %s autoscaling.keda.sh/paused-replicas=%d --overwrite", scaledObjectName, testNamespace, value))
assert.NoErrorf(t, err, "cannot execute command - %s", err)
}

func removeScaledObjectAnnotation(t assert.TestingT) {
_, err := ExecuteCommand(fmt.Sprintf("kubectl annotate scaledobject/%s -n %s autoscaling.keda.sh/paused-replicas- --overwrite", scaledObjectName, testNamespace))
assert.NoErrorf(t, err, "cannot execute command - %s", err)
}

func testPauseAt0(t *testing.T, kc *kubernetes.Clientset) {
t.Log("--- testing pausing at 0 ---")

upsertScaledObjectAnnotation(t, 0)
KubernetesScaleDeployment(t, kc, monitoredDeploymentName, 2, testNamespace)
assert.Truef(t, WaitForDeploymentReplicaReadyCount(t, kc, monitoredDeploymentName, testNamespace, 2, 60, testScaleOutWaitMin),
"monitoredDeploymentName replica count should be 2 after %d minute(s)", testScaleOutWaitMin)
Expand All @@ -180,9 +166,8 @@ func testPauseAt0(t *testing.T, kc *kubernetes.Clientset) {

func testScaleOut(t *testing.T, kc *kubernetes.Clientset, data templateData) {
t.Log("--- testing scale out ---")
data.CooldownPeriod = 15
KubectlApplyWithTemplate(t, data, "scaledObjectTemplate", scaledObjectTemplate)

removeScaledObjectAnnotation(t)
assert.Truef(t, WaitForDeploymentReplicaReadyCount(t, kc, monitoredDeploymentName, testNamespace, 2, 60, testScaleOutWaitMin),
"monitoredDeploymentName replica count should be 2 after %d minute(s)", testScaleOutWaitMin)

Expand All @@ -192,10 +177,8 @@ func testScaleOut(t *testing.T, kc *kubernetes.Clientset, data templateData) {

func testPauseAtN(t *testing.T, kc *kubernetes.Clientset, data templateData, n int) {
t.Log("--- testing pausing at N ---")
data.PausedReplicaCount = n
data.CooldownPeriod = 10
KubectlApplyWithTemplate(t, data, "scaledObjectAnnotatedTemplate", scaledObjectAnnotatedTemplate)

upsertScaledObjectAnnotation(t, n)
KubernetesScaleDeployment(t, kc, monitoredDeploymentName, 0, testNamespace)

assert.Truef(t, WaitForDeploymentReplicaReadyCount(t, kc, monitoredDeploymentName, testNamespace, 0, 60, testPauseAtNWaitMin),
Expand All @@ -207,9 +190,8 @@ func testPauseAtN(t *testing.T, kc *kubernetes.Clientset, data templateData, n i

func testScaleIn(t *testing.T, kc *kubernetes.Clientset, data templateData) {
t.Log("--- testing scale in ---")
data.CooldownPeriod = 15
KubectlApplyWithTemplate(t, data, "scaledObjectTemplate", scaledObjectTemplate)

removeScaledObjectAnnotation(t)
assert.Truef(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, testScaleInWaitMin),
"replica count should be 0 after %d minutes", testScaleInWaitMin)
}