Skip to content

Commit 40257c9

Browse files
committed
cvo: refactor always enabled caps processing
Refactor the code to be consistent with how the other options are processed. The `NewControllerContext` is a method on `Options` struct, so it does not make sense to pass it some options through the struct, and some options through method parameters. I went further and separated the validation (performed with all other validation) from conversion, resulting in two smaller methods instead one larger one. The result is slightly less efficient but more readable.
1 parent a37ab26 commit 40257c9

File tree

2 files changed

+41
-39
lines changed

2 files changed

+41
-39
lines changed

pkg/start/start.go

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2020
"k8s.io/apimachinery/pkg/fields"
2121
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
22+
"k8s.io/apimachinery/pkg/util/sets"
2223
"k8s.io/apimachinery/pkg/util/wait"
2324
"k8s.io/client-go/informers"
2425
"k8s.io/client-go/kubernetes"
@@ -162,6 +163,10 @@ func (o *Options) ValidateAndComplete() error {
162163
// Inject the cluster ID into PromQL queries in HyperShift
163164
o.InjectClusterIdIntoPromQL = o.HyperShift
164165

166+
if err := validateCapabilities(o.AlwaysEnableCapabilities); err != nil {
167+
return fmt.Errorf("--always-enable-capabilities: %w", err)
168+
}
169+
165170
return nil
166171
}
167172

@@ -172,10 +177,6 @@ func (o *Options) Run(ctx context.Context) error {
172177
if len(o.Exclude) > 0 {
173178
klog.Infof("Excluding manifests for %q", o.Exclude)
174179
}
175-
alwaysEnableCaps, unknownCaps := parseAlwaysEnableCapabilities(o.AlwaysEnableCapabilities)
176-
if len(unknownCaps) > 0 {
177-
return fmt.Errorf("--always-enable-capabilities was set with unknown capabilities: %v", unknownCaps)
178-
}
179180

180181
// initialize the core objects
181182
cb, err := newClientBuilder(o.Kubeconfig)
@@ -189,7 +190,7 @@ func (o *Options) Run(ctx context.Context) error {
189190
}
190191

191192
// initialize the controllers and attempt to load the payload information
192-
controllerCtx, err := o.NewControllerContext(cb, alwaysEnableCaps)
193+
controllerCtx, err := o.NewControllerContext(cb)
193194
if err != nil {
194195
return err
195196
}
@@ -474,7 +475,7 @@ type Context struct {
474475

475476
// NewControllerContext initializes the default Context for the current Options. It does
476477
// not start any background processes.
477-
func (o *Options) NewControllerContext(cb *ClientBuilder, alwaysEnableCapabilities []configv1.ClusterVersionCapability) (*Context, error) {
478+
func (o *Options) NewControllerContext(cb *ClientBuilder) (*Context, error) {
478479
client := cb.ClientOrDie("shared-informer")
479480
kubeClient := cb.KubeClientOrDie(internal.ConfigNamespace, useProtobuf)
480481
operatorClient := cb.OperatorClientOrDie("operator-client")
@@ -494,6 +495,7 @@ func (o *Options) NewControllerContext(cb *ClientBuilder, alwaysEnableCapabiliti
494495

495496
cvoKubeClient := cb.KubeClientOrDie(o.Namespace, useProtobuf)
496497
o.PromQLTarget.KubeClient = cvoKubeClient
498+
497499
cvo, err := cvo.New(
498500
o.NodeName,
499501
o.Namespace, o.Name,
@@ -515,7 +517,7 @@ func (o *Options) NewControllerContext(cb *ClientBuilder, alwaysEnableCapabiliti
515517
o.PromQLTarget,
516518
o.InjectClusterIdIntoPromQL,
517519
o.UpdateService,
518-
alwaysEnableCapabilities,
520+
stringsToCapabilities(o.AlwaysEnableCapabilities),
519521
)
520522
if err != nil {
521523
return nil, err
@@ -622,25 +624,22 @@ func (c *Context) InitializeFromPayload(ctx context.Context, restConfig *rest.Co
622624
return nil
623625
}
624626

625-
// parseAlwaysEnableCapabilities parses the string list of capabilities
626-
// into two lists of configv1.ClusterVersionCapability: known and unknown.
627-
func parseAlwaysEnableCapabilities(caps []string) ([]configv1.ClusterVersionCapability, []configv1.ClusterVersionCapability) {
628-
var (
629-
knownCaps []configv1.ClusterVersionCapability
630-
unknownCaps []configv1.ClusterVersionCapability
631-
)
632-
for _, c := range caps {
633-
known := false
634-
for _, kc := range configv1.KnownClusterVersionCapabilities {
635-
if configv1.ClusterVersionCapability(c) == kc {
636-
knownCaps = append(knownCaps, kc)
637-
known = true
638-
break
639-
}
640-
}
641-
if !known {
642-
unknownCaps = append(unknownCaps, configv1.ClusterVersionCapability(c))
643-
}
627+
func stringsToCapabilities(names []string) []configv1.ClusterVersionCapability {
628+
caps := make([]configv1.ClusterVersionCapability, len(names))
629+
for i, c := range names {
630+
caps[i] = configv1.ClusterVersionCapability(c)
631+
}
632+
return caps
633+
}
634+
635+
func validateCapabilities(caps []string) error {
636+
unknown := sets.New(caps...)
637+
for _, kc := range configv1.KnownClusterVersionCapabilities {
638+
unknown.Delete(string(kc))
644639
}
645-
return knownCaps, unknownCaps
640+
641+
if len(unknown) > 0 {
642+
return fmt.Errorf("unknown capabilities: %s", sets.List(unknown))
643+
}
644+
return nil
646645
}

pkg/start/start_integration_test.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,16 @@ func TestIntegrationCVO_initializeAndUpgrade(t *testing.T) {
184184
options.ReleaseImage = payloadImage1
185185
options.PayloadOverride = filepath.Join(dir, "0.0.1")
186186
options.leaderElection = getLeaderElectionConfig(ctx, cfg)
187-
alwaysEnableCapabilities := []configv1.ClusterVersionCapability{
188-
configv1.ClusterVersionCapabilityIngress,
187+
options.AlwaysEnableCapabilities = []string{string(configv1.ClusterVersionCapabilityIngress)}
188+
if err := options.ValidateAndComplete(); err != nil {
189+
t.Fatalf("incorrectly initialized options: %v", err)
189190
}
190-
controllers, err := options.NewControllerContext(cb, alwaysEnableCapabilities)
191+
controllers, err := options.NewControllerContext(cb)
191192
if err != nil {
192193
t.Fatal(err)
193194
}
194195

195-
worker := cvo.NewSyncWorker(retriever, cvo.NewResourceBuilder(cfg, cfg, nil, nil), 5*time.Second, wait.Backoff{Steps: 3}, "", "", record.NewFakeRecorder(100), payload.DefaultClusterProfile, alwaysEnableCapabilities)
196+
worker := cvo.NewSyncWorker(retriever, cvo.NewResourceBuilder(cfg, cfg, nil, nil), 5*time.Second, wait.Backoff{Steps: 3}, "", "", record.NewFakeRecorder(100), payload.DefaultClusterProfile, stringsToCapabilities(options.AlwaysEnableCapabilities))
196197
controllers.CVO.SetSyncWorkerForTesting(worker)
197198

198199
lock, err := createResourceLock(cb, options.Namespace, options.Name)
@@ -318,15 +319,16 @@ func TestIntegrationCVO_gracefulStepDown(t *testing.T) {
318319
options.ReleaseImage = payloadImage1
319320
options.PayloadOverride = filepath.Join(dir, "0.0.1")
320321
options.leaderElection = getLeaderElectionConfig(ctx, cfg)
321-
alwaysEnableCapabilities := []configv1.ClusterVersionCapability{
322-
configv1.ClusterVersionCapabilityIngress,
322+
options.AlwaysEnableCapabilities = []string{string(configv1.ClusterVersionCapabilityIngress)}
323+
if err := options.ValidateAndComplete(); err != nil {
324+
t.Fatalf("incorrectly initialized options: %v", err)
323325
}
324-
controllers, err := options.NewControllerContext(cb, alwaysEnableCapabilities)
326+
controllers, err := options.NewControllerContext(cb)
325327
if err != nil {
326328
t.Fatal(err)
327329
}
328330

329-
worker := cvo.NewSyncWorker(retriever, cvo.NewResourceBuilder(cfg, cfg, nil, nil), 5*time.Second, wait.Backoff{Steps: 3}, "", "", record.NewFakeRecorder(100), payload.DefaultClusterProfile, alwaysEnableCapabilities)
331+
worker := cvo.NewSyncWorker(retriever, cvo.NewResourceBuilder(cfg, cfg, nil, nil), 5*time.Second, wait.Backoff{Steps: 3}, "", "", record.NewFakeRecorder(100), payload.DefaultClusterProfile, stringsToCapabilities(options.AlwaysEnableCapabilities))
330332
controllers.CVO.SetSyncWorkerForTesting(worker)
331333

332334
lock, err := createResourceLock(cb, options.Namespace, options.Name)
@@ -514,15 +516,16 @@ metadata:
514516
options.ReleaseImage = payloadImage1
515517
options.PayloadOverride = payloadDir
516518
options.leaderElection = getLeaderElectionConfig(ctx, cfg)
517-
alwaysEnableCapabilities := []configv1.ClusterVersionCapability{
518-
configv1.ClusterVersionCapabilityIngress,
519+
options.AlwaysEnableCapabilities = []string{string(configv1.ClusterVersionCapabilityIngress)}
520+
if err := options.ValidateAndComplete(); err != nil {
521+
t.Fatalf("incorrectly initialized options: %v", err)
519522
}
520-
controllers, err := options.NewControllerContext(cb, alwaysEnableCapabilities)
523+
controllers, err := options.NewControllerContext(cb)
521524
if err != nil {
522525
t.Fatal(err)
523526
}
524527

525-
worker := cvo.NewSyncWorker(retriever, cvo.NewResourceBuilder(cfg, cfg, nil, nil), 5*time.Second, wait.Backoff{Steps: 3}, "", "", record.NewFakeRecorder(100), payload.DefaultClusterProfile, alwaysEnableCapabilities)
528+
worker := cvo.NewSyncWorker(retriever, cvo.NewResourceBuilder(cfg, cfg, nil, nil), 5*time.Second, wait.Backoff{Steps: 3}, "", "", record.NewFakeRecorder(100), payload.DefaultClusterProfile, stringsToCapabilities(options.AlwaysEnableCapabilities))
526529
controllers.CVO.SetSyncWorkerForTesting(worker)
527530

528531
lock, err := createResourceLock(cb, options.Namespace, options.Name)

0 commit comments

Comments
 (0)