Skip to content

Commit 1c02910

Browse files
marcolan018ciaranRoche
authored andcommitted
OCM-10460 | fix: don't overwrite existing autoscaler value in edit flow
1 parent ca17069 commit 1c02910

6 files changed

Lines changed: 403 additions & 106 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package autoscaler
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestAutoscaler(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Edit Austoscaler Suite")
13+
}

cmd/edit/autoscaler/cmd.go

Lines changed: 73 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ limitations under the License.
1717
package autoscaler
1818

1919
import (
20-
"os"
21-
"strconv"
20+
"context"
21+
"fmt"
2222

23-
commonUtils "github.com/openshift-online/ocm-common/pkg/utils"
2423
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
2524
"github.com/spf13/cobra"
2625

@@ -30,15 +29,13 @@ import (
3029
"github.com/openshift/rosa/pkg/rosa"
3130
)
3231

33-
const argsPrefix string = ""
34-
35-
var Cmd = &cobra.Command{
36-
Use: "autoscaler",
37-
Aliases: []string{"cluster-autoscaler"},
38-
Short: "Edit the autoscaler of a cluster",
39-
Long: "Configuring cluster-wide autoscaling behavior. At least one machine-pool should " +
40-
"have autoscaling enabled for the configuration to be active",
41-
Example: ` # Interactively edit an autoscaler to a cluster named "mycluster"
32+
const (
33+
argsPrefix = ""
34+
use = "autoscaler"
35+
short = "Edit the autoscaler of a cluster"
36+
long = "Configuring cluster-wide autoscaling behavior. At least one machine-pool should " +
37+
"have autoscaling enabled for the configuration to be active"
38+
example = ` # Interactively edit an autoscaler to a cluster named "mycluster"
4239
rosa edit autoscaler --cluster=mycluster --interactive
4340
4441
# Edit a cluster-autoscaler to skip nodes with local storage
@@ -48,118 +45,90 @@ var Cmd = &cobra.Command{
4845
rosa edit autoscaler --cluster=mycluster --log-verbosity 3
4946
5047
# Edit a cluster-autoscaler with total CPU constraints
51-
rosa edit autoscaler --cluster=mycluster --min-cores 10 --max-cores 100`,
52-
Run: run,
53-
Args: cobra.NoArgs,
54-
}
48+
rosa edit autoscaler --cluster=mycluster --min-cores 10 --max-cores 100`
49+
)
50+
51+
var aliases = []string{"cluster-autoscaler"}
5552

56-
var autoscalerArgs *clusterautoscaler.AutoscalerArgs
53+
func NewEditAutoscalerCommand() *cobra.Command {
54+
cmd := &cobra.Command{
55+
Use: use,
56+
Aliases: aliases,
57+
Short: short,
58+
Long: long,
59+
Example: example,
60+
Args: cobra.NoArgs,
61+
}
5762

58-
func init() {
59-
flags := Cmd.Flags()
63+
flags := cmd.Flags()
6064
flags.SortFlags = false
6165

62-
ocm.AddClusterFlag(Cmd)
66+
ocm.AddClusterFlag(cmd)
6367
interactive.AddFlag(flags)
64-
autoscalerArgs = clusterautoscaler.AddClusterAutoscalerFlags(Cmd, argsPrefix)
68+
autoscalerArgs := clusterautoscaler.AddClusterAutoscalerFlags(cmd, argsPrefix)
69+
cmd.Run = rosa.DefaultRunner(rosa.RuntimeWithOCM(), EditAutoscalerRunner(autoscalerArgs))
70+
return cmd
6571
}
6672

67-
func run(cmd *cobra.Command, _ []string) {
68-
r := rosa.NewRuntime().WithOCM()
69-
defer r.Cleanup()
73+
func EditAutoscalerRunner(autoscalerArgs *clusterautoscaler.AutoscalerArgs) rosa.CommandRunner {
74+
return func(ctx context.Context, r *rosa.Runtime, command *cobra.Command, _ []string) error {
75+
clusterKey := r.GetClusterKey()
76+
cluster, err := r.OCMClient.GetCluster(clusterKey, r.Creator)
77+
if err != nil {
78+
return err
79+
}
7080

71-
clusterKey := r.GetClusterKey()
81+
if cluster.Hypershift().Enabled() {
82+
return fmt.Errorf("Hosted Control Plane clusters do not support cluster-autoscaler configuration")
83+
}
7284

73-
cluster := r.FetchCluster()
85+
if cluster.State() != cmv1.ClusterStateReady {
86+
return fmt.Errorf("Cluster '%s' is not yet ready. Current state is '%s'", clusterKey, cluster.State())
87+
}
7488

75-
if cluster.Hypershift().Enabled() {
76-
r.Reporter.Errorf("Hosted Control Plane clusters do not support cluster-autoscaler configuration")
77-
os.Exit(1)
78-
}
89+
autoscaler, err := r.OCMClient.GetClusterAutoscaler(cluster.ID())
90+
if err != nil {
91+
return fmt.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
92+
cluster.ID(), err)
93+
}
7994

80-
if cluster.State() != cmv1.ClusterStateReady {
81-
r.Reporter.Errorf("Cluster '%s' is not yet ready. Current state is '%s'", clusterKey, cluster.State())
82-
os.Exit(1)
83-
}
95+
if autoscaler == nil {
96+
return fmt.Errorf("No autoscaler for cluster '%s' has been found. "+
97+
"You should first create it via 'rosa create autoscaler'", clusterKey)
98+
}
8499

85-
autoscaler, err := r.OCMClient.GetClusterAutoscaler(cluster.ID())
86-
if err != nil {
87-
r.Reporter.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
88-
cluster.ID(), err)
89-
os.Exit(1)
90-
}
100+
if !clusterautoscaler.IsAutoscalerSetViaCLI(command.Flags(), argsPrefix) && !interactive.Enabled() {
101+
interactive.Enable()
102+
r.Reporter.Infof("Enabling interactive mode")
103+
}
91104

92-
if autoscaler == nil {
93-
r.Reporter.Errorf("No autoscaler for cluster '%s' has been found. "+
94-
"You should first create it via 'rosa create autoscaler'", clusterKey)
95-
os.Exit(1)
96-
}
105+
r.Reporter.Debugf("Updating autoscaler for cluster '%s'", clusterKey)
97106

98-
if !clusterautoscaler.IsAutoscalerSetViaCLI(cmd.Flags(), argsPrefix) && !interactive.Enabled() {
99-
interactive.Enable()
100-
r.Reporter.Infof("Enabling interactive mode")
101-
}
107+
autoscalerArgs, err := clusterautoscaler.PrefillAutoscalerArgs(command, autoscalerArgs, autoscaler)
108+
if err != nil {
109+
return fmt.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
110+
cluster.ID(), err)
111+
}
102112

103-
r.Reporter.Debugf("Updating autoscaler for cluster '%s'", clusterKey)
104-
105-
if interactive.Enabled() {
106-
// pre-filling the parameters from the existing resource if running in interactive mode
107-
108-
autoscalerArgs.BalanceSimilarNodeGroups = autoscaler.BalanceSimilarNodeGroups()
109-
autoscalerArgs.SkipNodesWithLocalStorage = autoscaler.SkipNodesWithLocalStorage()
110-
autoscalerArgs.LogVerbosity = autoscaler.LogVerbosity()
111-
autoscalerArgs.MaxPodGracePeriod = autoscaler.MaxPodGracePeriod()
112-
autoscalerArgs.PodPriorityThreshold = autoscaler.PodPriorityThreshold()
113-
autoscalerArgs.IgnoreDaemonsetsUtilization = autoscaler.IgnoreDaemonsetsUtilization()
114-
autoscalerArgs.MaxNodeProvisionTime = autoscaler.MaxNodeProvisionTime()
115-
autoscalerArgs.BalancingIgnoredLabels = autoscaler.BalancingIgnoredLabels()
116-
autoscalerArgs.ResourceLimits.MaxNodesTotal = autoscaler.ResourceLimits().MaxNodesTotal()
117-
autoscalerArgs.ResourceLimits.Cores.Min = autoscaler.ResourceLimits().Cores().Min()
118-
autoscalerArgs.ResourceLimits.Cores.Max = autoscaler.ResourceLimits().Cores().Max()
119-
autoscalerArgs.ResourceLimits.Memory.Min = autoscaler.ResourceLimits().Memory().Min()
120-
autoscalerArgs.ResourceLimits.Memory.Max = autoscaler.ResourceLimits().Memory().Max()
121-
122-
// be aware we cannot easily pre-load GPU limits from existing configuration, so we'll have to
123-
// request it from scratch when interactive mode is on
124-
125-
autoscalerArgs.ScaleDown.Enabled = autoscaler.ScaleDown().Enabled()
126-
autoscalerArgs.ScaleDown.UnneededTime = autoscaler.ScaleDown().UnneededTime()
127-
autoscalerArgs.ScaleDown.DelayAfterAdd = autoscaler.ScaleDown().DelayAfterAdd()
128-
autoscalerArgs.ScaleDown.DelayAfterDelete = autoscaler.ScaleDown().DelayAfterDelete()
129-
autoscalerArgs.ScaleDown.DelayAfterFailure = autoscaler.ScaleDown().DelayAfterFailure()
130-
131-
utilizationThreshold, err := strconv.ParseFloat(
132-
autoscaler.ScaleDown().UtilizationThreshold(),
133-
commonUtils.MaxByteSize,
134-
)
113+
autoscalerArgs, err = clusterautoscaler.GetAutoscalerOptions(command.Flags(), "", false, autoscalerArgs)
135114
if err != nil {
136-
r.Reporter.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
115+
return fmt.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
137116
cluster.ID(), err)
138-
os.Exit(1)
139117
}
140-
autoscalerArgs.ScaleDown.UtilizationThreshold = utilizationThreshold
141-
}
142118

143-
autoscalerArgs, err := clusterautoscaler.GetAutoscalerOptions(cmd.Flags(), "", false, autoscalerArgs)
144-
if err != nil {
145-
r.Reporter.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
146-
cluster.ID(), err)
147-
os.Exit(1)
148-
}
119+
autoscalerConfig, err := clusterautoscaler.CreateAutoscalerConfig(autoscalerArgs)
120+
if err != nil {
121+
return fmt.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
122+
cluster.ID(), err)
123+
}
149124

150-
autoscalerConfig, err := clusterautoscaler.CreateAutoscalerConfig(autoscalerArgs)
151-
if err != nil {
152-
r.Reporter.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
153-
cluster.ID(), err)
154-
os.Exit(1)
155-
}
125+
_, err = r.OCMClient.UpdateClusterAutoscaler(cluster.ID(), autoscalerConfig)
126+
if err != nil {
127+
return fmt.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
128+
cluster.ID(), err)
129+
}
156130

157-
_, err = r.OCMClient.UpdateClusterAutoscaler(cluster.ID(), autoscalerConfig)
158-
if err != nil {
159-
r.Reporter.Errorf("Failed updating autoscaler configuration for cluster '%s': %s",
160-
cluster.ID(), err)
161-
os.Exit(1)
131+
r.Reporter.Infof("Successfully updated autoscaler configuration for cluster '%s'", cluster.ID())
132+
return nil
162133
}
163-
164-
r.Reporter.Infof("Successfully updated autoscaler configuration for cluster '%s'", cluster.ID())
165134
}

0 commit comments

Comments
 (0)