Skip to content

Commit d7ec3cd

Browse files
committed
Enhance the channel handling logic.
1 parent a12bd08 commit d7ec3cd

2 files changed

Lines changed: 150 additions & 5 deletions

File tree

controlplane/rosa/controllers/rosacontrolplane_controller.go

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -758,20 +758,60 @@ func (r *ROSAControlPlaneReconciler) updateOCMClusterSpec(rosaControlPlane *rosa
758758
updated = true
759759
}
760760

761-
// Check for channel changes
762-
desiredChannel := getEffectiveChannel(rosaControlPlane.Spec)
763-
desiredChannelGroup := getChannelGroupFromChannel(desiredChannel)
764-
761+
// Check for channel changes using sophisticated request handling logic
765762
// Reconstruct current channel from OCM cluster
766763
var currentChannel string
764+
var currentChannelGroup string
767765
if cluster.Version() != nil && cluster.Version().ChannelGroup() != "" {
766+
currentChannelGroup = cluster.Version().ChannelGroup()
768767
versionID := cluster.Version().ID()
769768
versionParts := strings.Split(versionID, ".")
770769
if len(versionParts) >= 2 {
771-
currentChannel = fmt.Sprintf("%s-%s.%s", cluster.Version().ChannelGroup(), versionParts[0], versionParts[1])
770+
currentChannel = fmt.Sprintf("%s-%s.%s", currentChannelGroup, versionParts[0], versionParts[1])
771+
}
772+
}
773+
774+
var desiredChannel string
775+
var desiredChannelGroup string
776+
777+
// Case 1: User explicitly set channel field - use it directly
778+
if rosaControlPlane.Spec.Channel != "" {
779+
desiredChannel = rosaControlPlane.Spec.Channel
780+
desiredChannelGroup = getChannelGroupFromChannel(desiredChannel)
781+
} else {
782+
// Case 2 & 3: User set channelGroup (or using default)
783+
requestedChannelGroup := string(rosaControlPlane.Spec.ChannelGroup)
784+
785+
// Case 2: channelGroup matches current channel's group - no update needed
786+
if requestedChannelGroup == currentChannelGroup {
787+
// No change needed, keep current channel
788+
desiredChannel = currentChannel
789+
desiredChannelGroup = currentChannelGroup
790+
} else {
791+
// Case 3: New channelGroup - intelligently construct new channel
792+
// Try to preserve current Y-stream: ${new_channel_group}-${current_channel_Y}
793+
if currentChannel != "" {
794+
// Extract Y-stream from current channel (e.g., "stable-4.18" -> "4.18")
795+
parts := strings.Split(currentChannel, "-")
796+
if len(parts) == 2 {
797+
currentYStream := parts[1]
798+
desiredChannel = fmt.Sprintf("%s-%s", requestedChannelGroup, currentYStream)
799+
desiredChannelGroup = requestedChannelGroup
800+
}
801+
}
802+
803+
// Fallback: derive from version if we couldn't preserve Y-stream
804+
if desiredChannel == "" {
805+
versionParts := strings.Split(rosaControlPlane.Spec.Version, ".")
806+
if len(versionParts) >= 2 {
807+
desiredChannel = fmt.Sprintf("%s-%s.%s", requestedChannelGroup, versionParts[0], versionParts[1])
808+
desiredChannelGroup = requestedChannelGroup
809+
}
810+
}
772811
}
773812
}
774813

814+
// Only update if channel actually changed
775815
if desiredChannel != currentChannel && desiredChannel != "" {
776816
ocmClusterSpec.Channel = desiredChannel
777817
ocmClusterSpec.ChannelGroup = desiredChannelGroup

controlplane/rosa/controllers/rosacontrolplane_controller_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,111 @@ func TestUpdateOCMClusterSpec(t *testing.T) {
233233
g.Expect(updated).To(BeTrue())
234234
g.Expect(ocmSpec).To(Equal(expectedOCMSpec))
235235
})
236+
237+
// Test case 8: Channel explicitly set - use it directly
238+
t.Run("Channel explicitly set", func(t *testing.T) {
239+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
240+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
241+
Channel: "eus-4.18",
242+
ChannelGroup: rosacontrolplanev1.Stable, // Different from channel, but channel takes precedence
243+
Version: "4.16.5",
244+
},
245+
}
246+
247+
mockCluster, _ := v1.NewCluster().
248+
Version(v1.NewVersion().
249+
ID("4.16.5").
250+
ChannelGroup("stable")).
251+
Build()
252+
253+
expectedOCMSpec := ocm.Spec{
254+
Channel: "eus-4.18",
255+
ChannelGroup: "eus",
256+
}
257+
258+
reconciler := &ROSAControlPlaneReconciler{}
259+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
260+
261+
g.Expect(updated).To(BeTrue())
262+
g.Expect(ocmSpec.Channel).To(Equal("eus-4.18"))
263+
g.Expect(ocmSpec.ChannelGroup).To(Equal("eus"))
264+
})
265+
266+
// Test case 9: ChannelGroup matches current - no update
267+
t.Run("ChannelGroup matches current channel group - no update", func(t *testing.T) {
268+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
269+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
270+
ChannelGroup: rosacontrolplanev1.Stable,
271+
Version: "4.16.5",
272+
},
273+
}
274+
275+
mockCluster, _ := v1.NewCluster().
276+
Version(v1.NewVersion().
277+
ID("4.18.3").
278+
ChannelGroup("stable")).
279+
Build()
280+
281+
reconciler := &ROSAControlPlaneReconciler{}
282+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
283+
284+
g.Expect(updated).To(BeFalse())
285+
g.Expect(ocmSpec.Channel).To(Equal(""))
286+
})
287+
288+
// Test case 10: New channelGroup - preserve Y-stream
289+
t.Run("New channelGroup preserves current Y-stream", func(t *testing.T) {
290+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
291+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
292+
ChannelGroup: rosacontrolplanev1.EUS, // Changing from stable to eus
293+
Version: "4.16.5",
294+
},
295+
}
296+
297+
// Current cluster is on stable-4.18
298+
mockCluster, _ := v1.NewCluster().
299+
Version(v1.NewVersion().
300+
ID("4.18.3").
301+
ChannelGroup("stable")).
302+
Build()
303+
304+
expectedOCMSpec := ocm.Spec{
305+
Channel: "eus-4.18", // Preserves 4.18 Y-stream from current
306+
ChannelGroup: "eus",
307+
}
308+
309+
reconciler := &ROSAControlPlaneReconciler{}
310+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
311+
312+
g.Expect(updated).To(BeTrue())
313+
g.Expect(ocmSpec.Channel).To(Equal("eus-4.18"))
314+
g.Expect(ocmSpec.ChannelGroup).To(Equal("eus"))
315+
})
316+
317+
// Test case 11: New channelGroup, no current channel - derive from version
318+
t.Run("New channelGroup with no current channel - derive from version", func(t *testing.T) {
319+
rosaControlPlane := &rosacontrolplanev1.ROSAControlPlane{
320+
Spec: rosacontrolplanev1.RosaControlPlaneSpec{
321+
ChannelGroup: rosacontrolplanev1.EUS,
322+
Version: "4.16.5",
323+
},
324+
}
325+
326+
// Cluster has no version info (edge case)
327+
mockCluster, _ := v1.NewCluster().Build()
328+
329+
expectedOCMSpec := ocm.Spec{
330+
Channel: "eus-4.16", // Derives from version
331+
ChannelGroup: "eus",
332+
}
333+
334+
reconciler := &ROSAControlPlaneReconciler{}
335+
ocmSpec, updated := reconciler.updateOCMClusterSpec(rosaControlPlane, mockCluster)
336+
337+
g.Expect(updated).To(BeTrue())
338+
g.Expect(ocmSpec.Channel).To(Equal("eus-4.16"))
339+
g.Expect(ocmSpec.ChannelGroup).To(Equal("eus"))
340+
})
236341
}
237342

238343
func TestValidateControlPlaneSpec(t *testing.T) {

0 commit comments

Comments
 (0)