Skip to content

Commit e36e77b

Browse files
authored
Merge pull request #5903 from tinaafitz/channel-support
✨ add Channel to the ROSA ControlPlane and AvailableChannels to the ROSA ControlPlane status.
2 parents c1d4074 + 72a9c22 commit e36e77b

File tree

11 files changed

+233
-22
lines changed

11 files changed

+233
-22
lines changed

config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,19 @@ spec:
101101
rule: self == oldSelf
102102
- message: billingAccount must be a valid AWS account ID
103103
rule: self.matches('^[0-9]{12}$')
104+
channel:
105+
description: |-
106+
Channel is the Y-stream OpenShift channel to use for this cluster, for example "stable-4.16" or "eus-4.16".
107+
This determines which Y-stream versions are available for upgrades.
108+
When not specified, OCM will determine the appropriate channel based on the cluster version.
109+
If Channel is set, ChannelGroup will be ignored.
110+
pattern: ^(stable|eus|fast|candidate|nightly)-[0-9]+\.[0-9]+$
111+
type: string
104112
channelGroup:
105-
default: stable
106-
description: OpenShift version channel group, default is stable.
113+
description: |-
114+
OpenShift version channel group.
115+
When not specified, OCM will determine the appropriate channel group based on the cluster version.
116+
This field will be deprecated in a future release in favor of the Channel field.
107117
enum:
108118
- stable
109119
- eus
@@ -935,7 +945,6 @@ spec:
935945
Required if RosaRoleConfigRef is not specified.
936946
type: string
937947
required:
938-
- channelGroup
939948
- region
940949
- rosaClusterName
941950
- version
@@ -944,6 +953,11 @@ spec:
944953
status:
945954
description: RosaControlPlaneStatus defines the observed state of ROSAControlPlane.
946955
properties:
956+
availableChannels:
957+
description: Available channels for the ROSA hosted control plane.
958+
items:
959+
type: string
960+
type: array
947961
availableUpgrades:
948962
description: Available upgrades for the ROSA hosted control plane.
949963
items:

controlplane/rosa/api/v1beta2/rosacontrolplane_types.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,22 @@ type RosaControlPlaneSpec struct { //nolint: maligned
134134
// OpenShift semantic version, for example "4.14.5".
135135
Version string `json:"version"`
136136

137-
// OpenShift version channel group, default is stable.
137+
// OpenShift version channel group.
138+
// When not specified, OCM will determine the appropriate channel group based on the cluster version.
139+
// This field will be deprecated in a future release in favor of the Channel field.
138140
//
141+
// +optional
139142
// +kubebuilder:validation:Enum=stable;eus;fast;candidate;nightly
140-
// +kubebuilder:default=stable
141-
ChannelGroup ChannelGroupType `json:"channelGroup"`
143+
ChannelGroup ChannelGroupType `json:"channelGroup,omitempty"`
144+
145+
// Channel is the Y-stream OpenShift channel to use for this cluster, for example "stable-4.16" or "eus-4.16".
146+
// This determines which Y-stream versions are available for upgrades.
147+
// When not specified, OCM will determine the appropriate channel based on the cluster version.
148+
// If Channel is set, ChannelGroup will be ignored.
149+
//
150+
// +optional
151+
// +kubebuilder:validation:Pattern:=`^(stable|eus|fast|candidate|nightly)-[0-9]+\.[0-9]+$`
152+
Channel string `json:"channel,omitempty"`
142153

143154
// FIPS configures FIPS-validated / Modules in Process cryptographic libraries.
144155
// FIPS (Federal Information Processing Standard) 140-2 is a U.S. government standard
@@ -894,6 +905,9 @@ type RosaControlPlaneStatus struct {
894905

895906
// Available upgrades for the ROSA hosted control plane.
896907
AvailableUpgrades []string `json:"availableUpgrades,omitempty"`
908+
909+
// Available channels for the ROSA hosted control plane.
910+
AvailableChannels []string `json:"availableChannels,omitempty"`
897911
}
898912

899913
// +kubebuilder:object:root=true

controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controlplane/rosa/controllers/rosacontrolplane_controller.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,10 @@ func (r *ROSAControlPlaneReconciler) reconcileClusterVersion(rosaScope *scope.RO
630630

631631
if cluster.Version() != nil {
632632
rosaScope.ControlPlane.Status.AvailableUpgrades = cluster.Version().AvailableUpgrades()
633+
versionID := rosa.CreateVersionID(rosaScope.ControlPlane.Spec.Version, string(rosaScope.ControlPlane.Spec.ChannelGroup), rosaScope.ControlPlane.Spec.Channel)
634+
if availableChannels, err := ocmClient.GetAvailableChannels(versionID); err == nil && availableChannels != nil {
635+
rosaScope.ControlPlane.Status.AvailableChannels = availableChannels
636+
}
633637
}
634638

635639
// Set the version gate to WaitForAcknowledge as the previous upgrade is applied.
@@ -758,12 +762,18 @@ func (r *ROSAControlPlaneReconciler) updateOCMClusterSpec(rosaControlPlane *rosa
758762
updated = true
759763
}
760764

761-
if rosaControlPlane.Spec.ChannelGroup != "" {
762-
channelGroup := string(rosaControlPlane.Spec.ChannelGroup)
763-
if cluster.Version() == nil || cluster.Version().ChannelGroup() != channelGroup {
764-
ocmClusterSpec.ChannelGroup = channelGroup
765+
// Handle channel and channelGroup updates.
766+
// If neither is set, OCM will set the channel and channelGroup based on cluster version.
767+
if rosaControlPlane.Spec.Channel != "" {
768+
// Channel takes priority over channelGroup
769+
if cluster.Channel() != rosaControlPlane.Spec.Channel {
770+
ocmClusterSpec.Channel = rosaControlPlane.Spec.Channel
765771
updated = true
766772
}
773+
} else if rosaControlPlane.Spec.ChannelGroup != "" && cluster.Version() != nil && cluster.Version().ChannelGroup() != string(rosaControlPlane.Spec.ChannelGroup) {
774+
// Set channelGroup (legacy field)
775+
ocmClusterSpec.ChannelGroup = string(rosaControlPlane.Spec.ChannelGroup)
776+
updated = true
767777
}
768778

769779
if rosaControlPlane.Spec.AutoNode != nil {
@@ -1113,6 +1123,7 @@ func (r *ROSAControlPlaneReconciler) reconcileClusterAdminPassword(ctx context.C
11131123
func validateControlPlaneSpec(ocmClient rosa.OCMClient, rosaControlPlane *rosacontrolplanev1.ROSAControlPlane) (string, error) {
11141124
version := rosaControlPlane.Spec.Version
11151125
channelGroup := string(rosaControlPlane.Spec.ChannelGroup)
1126+
11161127
valid, err := ocmClient.ValidateHypershiftVersion(version, channelGroup)
11171128
if err != nil {
11181129
return "", fmt.Errorf("error validating version in this channelGroup : %w", err)
@@ -1163,8 +1174,7 @@ func buildOCMClusterSpec(controlPlaneSpec rosacontrolplanev1.RosaControlPlaneSpe
11631174
DomainPrefix: controlPlaneSpec.DomainPrefix,
11641175
Region: controlPlaneSpec.Region,
11651176
MultiAZ: true,
1166-
Version: ocm.CreateVersionID(controlPlaneSpec.Version, string(controlPlaneSpec.ChannelGroup)),
1167-
ChannelGroup: string(controlPlaneSpec.ChannelGroup),
1177+
Version: rosa.CreateVersionID(controlPlaneSpec.Version, string(controlPlaneSpec.ChannelGroup), controlPlaneSpec.Channel),
11681178
DisableWorkloadMonitoring: ptr.To(true),
11691179
DefaultIngress: ocm.NewDefaultIngressSpec(), // n.b. this is a no-op when it's set to the default value
11701180
ComputeMachineType: controlPlaneSpec.DefaultMachinePoolSpec.InstanceType,
@@ -1292,6 +1302,17 @@ func buildOCMClusterSpec(controlPlaneSpec rosacontrolplanev1.RosaControlPlaneSpe
12921302
S3ConfigBucketPrefix: controlPlaneSpec.S3LogForwarder.S3ConfigBucketPrefix,
12931303
}
12941304
}
1305+
1306+
// Handle channel and channelGroup.
1307+
// If neither is set, OCM will set the channel and channelGroup based on cluster version.
1308+
if controlPlaneSpec.Channel != "" {
1309+
// Set channel and ignore channelGroup
1310+
ocmClusterSpec.Channel = controlPlaneSpec.Channel
1311+
} else if controlPlaneSpec.ChannelGroup != "" {
1312+
// Set channelGroup (legacy field)
1313+
ocmClusterSpec.ChannelGroup = string(controlPlaneSpec.ChannelGroup)
1314+
}
1315+
12951316
return ocmClusterSpec, nil
12961317
}
12971318

controlplane/rosa/controllers/rosacontrolplane_controller_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,97 @@ func TestUpdateOCMClusterSpec(t *testing.T) {
234234
g.Expect(updated).To(BeTrue())
235235
g.Expect(ocmSpec).To(Equal(expectedOCMSpec))
236236
})
237+
238+
// Test case 8: Channel explicitly set - use it directly
239+
t.Run("Channel explicitly set", func(t *testing.T) {
240+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
241+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
242+
Channel: "eus-4.18",
243+
ChannelGroup: rosacontrolplanev1.Stable, // Different from channel, but channel takes precedence
244+
Version: "4.16.5",
245+
},
246+
}
247+
248+
mockCluster, _ := v1.NewCluster().
249+
Version(v1.NewVersion().
250+
ID("4.16.5").
251+
ChannelGroup("stable")).
252+
Build()
253+
254+
reconciler := &ROSAControlPlaneReconciler{}
255+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
256+
257+
g.Expect(updated).To(BeTrue())
258+
g.Expect(ocmSpec.Channel).To(Equal("eus-4.18"))
259+
g.Expect(ocmSpec.ChannelGroup).To(BeEmpty())
260+
})
261+
262+
// Test case 9: ChannelGroup matches current - no update
263+
t.Run("ChannelGroup matches current channel group - no update", func(t *testing.T) {
264+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
265+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
266+
ChannelGroup: rosacontrolplanev1.Stable,
267+
Version: "4.16.5",
268+
},
269+
}
270+
271+
mockCluster, _ := v1.NewCluster().
272+
Version(v1.NewVersion().
273+
ID("4.18.3").
274+
ChannelGroup("stable")).
275+
Build()
276+
277+
reconciler := &ROSAControlPlaneReconciler{}
278+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
279+
280+
g.Expect(updated).To(BeFalse())
281+
g.Expect(ocmSpec.Channel).To(BeEmpty())
282+
g.Expect(ocmSpec.ChannelGroup).To(BeEmpty())
283+
})
284+
285+
// Test case 10: ChannelGroup changes - update channelGroup
286+
t.Run("ChannelGroup changes from stable to eus", func(t *testing.T) {
287+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
288+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
289+
ChannelGroup: rosacontrolplanev1.Eus, // Changing from stable to eus
290+
Version: "4.16.5",
291+
},
292+
}
293+
294+
mockCluster, _ := v1.NewCluster().
295+
Version(v1.NewVersion().
296+
ID("4.18.3").
297+
ChannelGroup("stable")).
298+
Build()
299+
300+
reconciler := &ROSAControlPlaneReconciler{}
301+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
302+
303+
g.Expect(updated).To(BeTrue())
304+
g.Expect(ocmSpec.ChannelGroup).To(Equal("eus"))
305+
g.Expect(ocmSpec.Channel).To(BeEmpty())
306+
})
307+
308+
// Test case 11: ChannelGroup set, no current version info
309+
t.Run("ChannelGroup set with no current version info", func(t *testing.T) {
310+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
311+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
312+
ChannelGroup: rosacontrolplanev1.Eus,
313+
Version: "4.16.5",
314+
},
315+
}
316+
317+
// Cluster has no version info (edge case)
318+
// When version is nil, we skip the channelGroup update
319+
mockCluster, _ := v1.NewCluster().Build()
320+
321+
reconciler := &ROSAControlPlaneReconciler{}
322+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
323+
324+
g.Expect(updated).To(BeFalse())
325+
g.Expect(ocmSpec.ChannelGroup).To(BeEmpty())
326+
g.Expect(ocmSpec.Channel).To(BeEmpty())
327+
})
237328
}
238329

239330
func TestValidateControlPlaneSpec(t *testing.T) {
@@ -455,6 +546,9 @@ func TestRosaControlPlaneReconcileStatusVersion(t *testing.T) {
455546
m.UpdateCluster(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(clusterKey string, creator *rosaaws.Creator, config ocm.Spec) error {
456547
return nil
457548
}).Times(1)
549+
m.GetAvailableChannels(gomock.Any()).DoAndReturn(func(versionID string) ([]string, error) {
550+
return []string{"stable-4.15"}, nil
551+
}).Times(1)
458552
m.GetIdentityProviders(gomock.Any()).DoAndReturn(func(cclusterID string) ([]*v1.IdentityProvider, error) {
459553
ip := []*v1.IdentityProvider{}
460554
return ip, nil

controlplane/rosa/webhooks/rosacontrolplane_webhook.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ func (w *ROSAControlPlane) ValidateUpdate(_ context.Context, oldObj, newObj runt
135135
allErrs = append(allErrs, err)
136136
}
137137

138+
if err := w.validateChannel(r); err != nil {
139+
allErrs = append(allErrs, err)
140+
}
141+
138142
allErrs = append(allErrs, w.validateROSANetwork(r)...)
139143
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)
140144

@@ -274,6 +278,22 @@ func (w *ROSAControlPlane) validateRosaRoleConfig(r *rosacontrolplanev1.ROSACont
274278
return nil
275279
}
276280

281+
// validateChannel validates that the specified channel exists in the available channels list.
282+
func (w *ROSAControlPlane) validateChannel(r *rosacontrolplanev1.ROSAControlPlane) *field.Error {
283+
if r.Spec.Channel == "" || len(r.Status.AvailableChannels) == 0 {
284+
return nil
285+
}
286+
287+
for _, ch := range r.Status.AvailableChannels {
288+
if ch == r.Spec.Channel {
289+
return nil
290+
}
291+
}
292+
293+
return field.Invalid(field.NewPath("spec.channel"), r.Spec.Channel,
294+
fmt.Sprintf("channel must be one of the available channels: %v", r.Status.AvailableChannels))
295+
}
296+
277297
func (w *ROSAControlPlane) validateROSANetworkRef(r *rosacontrolplanev1.ROSAControlPlane) *field.Error {
278298
if r.Spec.ROSANetworkRef != nil {
279299
if r.Spec.Subnets != nil {

exp/controllers/rosamachinepool_controller.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/google/go-cmp/cmp"
1212
"github.com/google/go-cmp/cmp/cmpopts"
1313
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
14-
"github.com/openshift/rosa/pkg/ocm"
1514
"github.com/pkg/errors"
1615
corev1 "k8s.io/api/core/v1"
1716
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -298,7 +297,7 @@ func (r *ROSAMachinePoolReconciler) reconcileNormal(ctx context.Context,
298297
return ctrl.Result{RequeueAfter: time.Second * 60}, nil
299298
}
300299

301-
npBuilder := nodePoolBuilder(rosaMachinePool.Spec, machinePool.Spec, machinePoolScope.ControlPlane.Spec.ChannelGroup)
300+
npBuilder := nodePoolBuilder(rosaMachinePool.Spec, machinePool.Spec, machinePoolScope.ControlPlane.Spec.ChannelGroup, machinePoolScope.ControlPlane.Spec.Channel)
302301
nodePoolSpec, err := npBuilder.Build()
303302
if err != nil {
304303
return ctrl.Result{}, fmt.Errorf("failed to build rosa nodepool: %w", err)
@@ -410,7 +409,7 @@ func (r *ROSAMachinePoolReconciler) updateNodePool(machinePoolScope *scope.RosaM
410409
desiredSpec.AdditionalSecurityGroups = nil
411410
desiredSpec.AdditionalTags = nil
412411

413-
npBuilder := nodePoolBuilder(desiredSpec, machinePoolScope.MachinePool.Spec, machinePoolScope.ControlPlane.Spec.ChannelGroup)
412+
npBuilder := nodePoolBuilder(desiredSpec, machinePoolScope.MachinePool.Spec, machinePoolScope.ControlPlane.Spec.ChannelGroup, machinePoolScope.ControlPlane.Spec.Channel)
414413
nodePoolSpec, err := npBuilder.Build()
415414
if err != nil {
416415
return nil, fmt.Errorf("failed to build nodePool spec: %w", err)
@@ -467,7 +466,7 @@ func validateMachinePoolSpec(machinePoolScope *scope.RosaMachinePoolScope) (*str
467466
return nil, nil
468467
}
469468

470-
func nodePoolBuilder(rosaMachinePoolSpec expinfrav1.RosaMachinePoolSpec, machinePoolSpec clusterv1.MachinePoolSpec, controlPlaneChannelGroup rosacontrolplanev1.ChannelGroupType) *cmv1.NodePoolBuilder {
469+
func nodePoolBuilder(rosaMachinePoolSpec expinfrav1.RosaMachinePoolSpec, machinePoolSpec clusterv1.MachinePoolSpec, controlPlaneChannelGroup rosacontrolplanev1.ChannelGroupType, controlPlaneChannel string) *cmv1.NodePoolBuilder {
471470
npBuilder := cmv1.NewNodePool().ID(rosaMachinePoolSpec.NodePoolName).
472471
Labels(rosaMachinePoolSpec.Labels).
473472
AutoRepair(rosaMachinePoolSpec.AutoRepair)
@@ -519,7 +518,7 @@ func nodePoolBuilder(rosaMachinePoolSpec expinfrav1.RosaMachinePoolSpec, machine
519518
npBuilder.AWSNodePool(awsNodePool)
520519

521520
if rosaMachinePoolSpec.Version != "" {
522-
npBuilder.Version(cmv1.NewVersion().ID(ocm.CreateVersionID(rosaMachinePoolSpec.Version, string(controlPlaneChannelGroup))))
521+
npBuilder.Version(cmv1.NewVersion().ID(rosa.CreateVersionID(rosaMachinePoolSpec.Version, string(controlPlaneChannelGroup), controlPlaneChannel)))
523522
}
524523

525524
if rosaMachinePoolSpec.NodeDrainGracePeriod != nil {

exp/controllers/rosamachinepool_controller_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func TestNodePoolToRosaMachinePoolSpec(t *testing.T) {
7878
Replicas: ptr.To[int32](2),
7979
}
8080

81-
nodePoolBuilder := nodePoolBuilder(rosaMachinePoolSpec, machinePoolSpec, rosacontrolplanev1.Stable)
81+
nodePoolBuilder := nodePoolBuilder(rosaMachinePoolSpec, machinePoolSpec, rosacontrolplanev1.Stable, "")
8282
nodePoolSpec, err := nodePoolBuilder.Build()
8383
g.Expect(err).ToNot(HaveOccurred())
8484

@@ -306,7 +306,7 @@ func TestRosaMachinePoolReconcile(t *testing.T) {
306306
result: ctrl.Result{RequeueAfter: time.Second * 60},
307307
expect: func(m *mocks.MockOCMClientMockRecorder) {
308308
m.GetNodePool(gomock.Any(), gomock.Any()).DoAndReturn(func(clusterId string, nodePoolID string) (*cmv1.NodePool, bool, error) {
309-
nodePoolBuilder := nodePoolBuilder(rosaMachinePool(1).Spec, ownerMachinePool(1).Spec, rosacontrolplanev1.Stable)
309+
nodePoolBuilder := nodePoolBuilder(rosaMachinePool(1).Spec, ownerMachinePool(1).Spec, rosacontrolplanev1.Stable, "")
310310
nodePool, err := nodePoolBuilder.ID("node-pool-1").Build()
311311
g.Expect(err).To(BeNil())
312312
return nodePool, true, nil
@@ -345,7 +345,7 @@ func TestRosaMachinePoolReconcile(t *testing.T) {
345345
result: ctrl.Result{},
346346
expect: func(m *mocks.MockOCMClientMockRecorder) {
347347
m.GetNodePool(gomock.Any(), gomock.Any()).DoAndReturn(func(clusterId string, nodePoolID string) (*cmv1.NodePool, bool, error) {
348-
nodePoolBuilder := nodePoolBuilder(rosaMachinePool(2).Spec, ownerMachinePool(2).Spec, rosacontrolplanev1.Stable)
348+
nodePoolBuilder := nodePoolBuilder(rosaMachinePool(2).Spec, ownerMachinePool(2).Spec, rosacontrolplanev1.Stable, "")
349349
statusBuilder := (&cmv1.NodePoolStatusBuilder{}).CurrentReplicas(1)
350350
autoscalingBuilder := (&cmv1.NodePoolAutoscalingBuilder{}).MinReplica(1).MaxReplica(1)
351351
nodePool, err := nodePoolBuilder.ID("node-pool-1").Autoscaling(autoscalingBuilder).Replicas(1).Status(statusBuilder).Build()
@@ -500,7 +500,7 @@ func TestRosaMachinePoolReconcile(t *testing.T) {
500500
MaxUnavailable: ptr.To(intstr.FromInt32(0)),
501501
},
502502
}
503-
nodePoolBuilder := nodePoolBuilder(rosaSpec, ownerMachinePool(4).Spec, rosacontrolplanev1.Stable)
503+
nodePoolBuilder := nodePoolBuilder(rosaSpec, ownerMachinePool(4).Spec, rosacontrolplanev1.Stable, "")
504504
statusBuilder := (&cmv1.NodePoolStatusBuilder{}).CurrentReplicas(1)
505505
nodeGrace := (&cmv1.ValueBuilder{}).Unit("s").Value(0)
506506
nodePool, err := nodePoolBuilder.ID("test-nodepool").Replicas(1).Status(statusBuilder).AutoRepair(true).NodeDrainGracePeriod(nodeGrace).Build()
@@ -659,7 +659,7 @@ func TestRosaMachinePoolReconcile(t *testing.T) {
659659
nodePoolName := "node-pool-1"
660660
expect := func(m *mocks.MockOCMClientMockRecorder) {
661661
m.GetNodePool(gomock.Any(), gomock.Any()).DoAndReturn(func(clusterId string, nodePoolID string) (*cmv1.NodePool, bool, error) {
662-
nodePoolBuilder := nodePoolBuilder(mp.Spec, omp.Spec, rosacontrolplanev1.Stable)
662+
nodePoolBuilder := nodePoolBuilder(mp.Spec, omp.Spec, rosacontrolplanev1.Stable, "")
663663
nodePool, err := nodePoolBuilder.ID(nodePoolName).Build()
664664
g.Expect(err).NotTo(HaveOccurred())
665665
return nodePool, true, nil

0 commit comments

Comments
 (0)