Skip to content

Commit 13060bc

Browse files
Merge pull request #306 from alexander-demicev/versionfix
Use spec.Version field as primarily source
2 parents 69c6985 + 5d61ace commit 13060bc

18 files changed

+121
-48
lines changed

bootstrap/api/v1beta1/rke2config_types.go

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ type RKE2AgentConfig struct {
148148

149149
// Version specifies the rke2 version.
150150
// This field will be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version will be used instead.
151+
// +kubebuilder:validation:Pattern="v(\\d\\.\\d{2}\\.\\d)\\+rke2r\\d"
151152
//+optional
152153
Version string `json:"version,omitempty"`
153154

bootstrap/config/crd/bases/bootstrap.cluster.x-k8s.io_rke2configs.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,7 @@ spec:
892892
description: |-
893893
Version specifies the rke2 version.
894894
This field will be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version will be used instead.
895+
pattern: v(\d\.\d{2}\.\d)\+rke2r\d
895896
type: string
896897
type: object
897898
files:

bootstrap/config/crd/bases/bootstrap.cluster.x-k8s.io_rke2configtemplates.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ spec:
875875
description: |-
876876
Version specifies the rke2 version.
877877
This field will be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version will be used instead.
878+
pattern: v(\d\.\d{2}\.\d)\+rke2r\d
878879
type: string
879880
type: object
880881
files:

bootstrap/internal/controllers/rke2config_controller.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,14 @@ type Scope struct {
278278
ControlPlane *controlplanev1.RKE2ControlPlane
279279
}
280280

281+
func (s *Scope) getDesiredVersion() string {
282+
if s.Machine.Spec.Version != nil && bsutil.IsRKE2Version(*s.Machine.Spec.Version) {
283+
return *s.Machine.Spec.Version
284+
}
285+
286+
return s.Config.Spec.AgentConfig.Version
287+
}
288+
281289
// SetupWithManager sets up the controller with the Manager.
282290
func (r *RKE2ConfigReconciler) SetupWithManager(mgr ctrl.Manager) error {
283291
if r.RKE2InitLock == nil {
@@ -363,6 +371,7 @@ func (r *RKE2ConfigReconciler) handleClusterNotInitialized(ctx context.Context,
363371
AgentConfig: scope.Config.Spec.AgentConfig,
364372
Ctx: ctx,
365373
Client: r.Client,
374+
Version: scope.getDesiredVersion(),
366375
})
367376
if err != nil {
368377
return ctrl.Result{}, err
@@ -417,7 +426,7 @@ func (r *RKE2ConfigReconciler) handleClusterNotInitialized(ctx context.Context,
417426
PreRKE2Commands: scope.Config.Spec.PreRKE2Commands,
418427
PostRKE2Commands: scope.Config.Spec.PostRKE2Commands,
419428
ConfigFile: initConfigFile,
420-
RKE2Version: scope.Config.Spec.AgentConfig.Version,
429+
RKE2Version: scope.getDesiredVersion(),
421430
WriteFiles: files,
422431
NTPServers: ntpServers,
423432
AdditionalCloudInit: scope.Config.Spec.AgentConfig.AdditionalUserData.Config,
@@ -567,6 +576,7 @@ func (r *RKE2ConfigReconciler) joinControlplane(ctx context.Context, scope *Scop
567576
AgentConfig: scope.Config.Spec.AgentConfig,
568577
Ctx: ctx,
569578
Client: r.Client,
579+
Version: scope.getDesiredVersion(),
570580
},
571581
)
572582
if err != nil {
@@ -627,7 +637,7 @@ func (r *RKE2ConfigReconciler) joinControlplane(ctx context.Context, scope *Scop
627637
PreRKE2Commands: scope.Config.Spec.PreRKE2Commands,
628638
PostRKE2Commands: scope.Config.Spec.PostRKE2Commands,
629639
ConfigFile: initConfigFile,
630-
RKE2Version: scope.Config.Spec.AgentConfig.Version,
640+
RKE2Version: scope.getDesiredVersion(),
631641
WriteFiles: files,
632642
NTPServers: ntpServers,
633643
AdditionalCloudInit: scope.Config.Spec.AgentConfig.AdditionalUserData.Config,
@@ -700,6 +710,7 @@ func (r *RKE2ConfigReconciler) joinWorker(ctx context.Context, scope *Scope) (re
700710
Client: r.Client,
701711
CloudProviderName: scope.ControlPlane.Spec.ServerConfig.CloudProviderName,
702712
CloudProviderConfigMap: scope.ControlPlane.Spec.ServerConfig.CloudProviderConfigMap,
713+
Version: scope.getDesiredVersion(),
703714
})
704715
if err != nil {
705716
return ctrl.Result{}, err
@@ -738,7 +749,7 @@ func (r *RKE2ConfigReconciler) joinWorker(ctx context.Context, scope *Scope) (re
738749
CISEnabled: scope.Config.Spec.AgentConfig.CISProfile != "",
739750
PostRKE2Commands: scope.Config.Spec.PostRKE2Commands,
740751
ConfigFile: wkJoinConfigFile,
741-
RKE2Version: scope.Config.Spec.AgentConfig.Version,
752+
RKE2Version: scope.getDesiredVersion(),
742753
WriteFiles: files,
743754
NTPServers: ntpServers,
744755
AdditionalCloudInit: scope.Config.Spec.AgentConfig.AdditionalUserData.Config,

controlplane/api/v1beta1/rke2controlplane_types.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
"regexp"
21+
2022
corev1 "k8s.io/api/core/v1"
2123
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2224
"k8s.io/apimachinery/pkg/util/intstr"
@@ -47,9 +49,8 @@ type RKE2ControlPlaneSpec struct {
4749
Replicas *int32 `json:"replicas,omitempty"`
4850

4951
// Version defines the desired Kubernetes version.
50-
// This is only a placeholder for now, and the RKE2ConfigSpec.AgentConfig.Version field should be used instead.
51-
// In future iterations, this field overrides the RKE2 Version specificied in RKE2ConfigSpec.AgentConfig.Version
52-
// which will be deprecated in newer versions of the API.
52+
// This field takes precedence over RKE2ConfigSpec.AgentConfig.Version (which is deprecated).
53+
// +kubebuilder:validation:Pattern="v(\\d\\.\\d{2}\\.\\d)\\+rke2r\\d"
5354
// +optional
5455
Version string `json:"version"`
5556

@@ -436,3 +437,21 @@ func (r *RKE2ControlPlane) GetConditions() clusterv1.Conditions {
436437
func (r *RKE2ControlPlane) SetConditions(conditions clusterv1.Conditions) {
437438
r.Status.Conditions = conditions
438439
}
440+
441+
// GetDesiredVersion returns the desired version of the RKE2ControlPlane using Spec.Version field as a default field.
442+
func (r *RKE2ControlPlane) GetDesiredVersion() string {
443+
if r.Spec.Version != "" && isRKE2Version(r.Spec.Version) {
444+
return r.Spec.Version
445+
}
446+
447+
return r.Spec.AgentConfig.Version
448+
}
449+
450+
// isRKE2Version checks if a string is an RKE2 version.
451+
func isRKE2Version(rke2Version string) bool {
452+
regexStr := "v(\\d\\.\\d{2}\\.\\d)\\+rke2r\\d"
453+
454+
regex, _ := regexp.Compile(regexStr)
455+
456+
return regex.MatchString(rke2Version)
457+
}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,7 @@ spec:
15371537
description: |-
15381538
Version specifies the rke2 version.
15391539
This field will be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version will be used instead.
1540+
pattern: v(\d\.\d{2}\.\d)\+rke2r\d
15401541
type: string
15411542
type: object
15421543
files:
@@ -2449,9 +2450,8 @@ spec:
24492450
version:
24502451
description: |-
24512452
Version defines the desired Kubernetes version.
2452-
This is only a placeholder for now, and the RKE2ConfigSpec.AgentConfig.Version field should be used instead.
2453-
In future iterations, this field overrides the RKE2 Version specificied in RKE2ConfigSpec.AgentConfig.Version
2454-
which will be deprecated in newer versions of the API.
2453+
This field takes precedence over RKE2ConfigSpec.AgentConfig.Version (which is deprecated).
2454+
pattern: v(\d\.\d{2}\.\d)\+rke2r\d
24552455
type: string
24562456
required:
24572457
- infrastructureRef

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ spec:
368368
description: |-
369369
Version specifies the rke2 version.
370370
This field will be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version will be used instead.
371+
pattern: v(\d\.\d{2}\.\d)\+rke2r\d
371372
type: string
372373
type: object
373374
files:
@@ -1300,9 +1301,8 @@ spec:
13001301
version:
13011302
description: |-
13021303
Version defines the desired Kubernetes version.
1303-
This is only a placeholder for now, and the RKE2ConfigSpec.AgentConfig.Version field should be used instead.
1304-
In future iterations, this field overrides the RKE2 Version specificied in RKE2ConfigSpec.AgentConfig.Version
1305-
which will be deprecated in newer versions of the API.
1304+
This field takes precedence over RKE2ConfigSpec.AgentConfig.Version (which is deprecated).
1305+
pattern: v(\d\.\d{2}\.\d)\+rke2r\d
13061306
type: string
13071307
required:
13081308
- infrastructureRef

controlplane/internal/controllers/rke2controlplane_controller.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,9 @@ func (r *RKE2ControlPlaneReconciler) reconcileEtcdMembers(ctx context.Context, c
609609
return errors.Wrap(err, "cannot get remote client to workload cluster")
610610
}
611611

612-
parsedVersion, err := semver.ParseTolerant(controlPlane.RCP.Spec.AgentConfig.Version)
612+
parsedVersion, err := semver.ParseTolerant(controlPlane.RCP.GetDesiredVersion())
613613
if err != nil {
614-
return errors.Wrapf(err, "failed to parse kubernetes version %q", controlPlane.RCP.Spec.AgentConfig.Version)
614+
return errors.Wrapf(err, "failed to parse kubernetes version %q", controlPlane.RCP.GetDesiredVersion())
615615
}
616616

617617
removedMembers, err := workloadCluster.ReconcileEtcdMembers(ctx, nodeNames, parsedVersion)

controlplane/internal/controllers/scale.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package controllers
1919
import (
2020
"context"
2121
"encoding/json"
22-
"fmt"
2322
"strings"
2423
"time"
2524

@@ -42,7 +41,6 @@ import (
4241
bootstrapv1 "github.com/rancher-sandbox/cluster-api-provider-rke2/bootstrap/api/v1beta1"
4342
controlplanev1 "github.com/rancher-sandbox/cluster-api-provider-rke2/controlplane/api/v1beta1"
4443
rke2 "github.com/rancher-sandbox/cluster-api-provider-rke2/pkg/rke2"
45-
bsutil "github.com/rancher-sandbox/cluster-api-provider-rke2/pkg/util"
4644
)
4745

4846
func (r *RKE2ControlPlaneReconciler) initializeControlPlane(
@@ -413,14 +411,11 @@ func (r *RKE2ControlPlaneReconciler) generateMachine(
413411
bootstrapRef *corev1.ObjectReference,
414412
failureDomain *string,
415413
) error {
416-
newVersion, err := bsutil.Rke2ToKubeVersion(rcp.Spec.AgentConfig.Version)
417-
if err != nil {
418-
return fmt.Errorf("failed to convert rke2 version to kubernetes version: %w", err)
419-
}
420-
421414
logger := log.FromContext(ctx)
422415

423-
logger.Info("Version checking...", "rke2-version", rcp.Spec.AgentConfig.Version, "machine-version: ", newVersion)
416+
rke2Version := rcp.GetDesiredVersion()
417+
418+
logger.Info("Version checking...", "rke2-version", rke2Version)
424419

425420
machine := &clusterv1.Machine{
426421
ObjectMeta: metav1.ObjectMeta{
@@ -433,7 +428,7 @@ func (r *RKE2ControlPlaneReconciler) generateMachine(
433428
},
434429
Spec: clusterv1.MachineSpec{
435430
ClusterName: cluster.Name,
436-
Version: &newVersion,
431+
Version: &rke2Version,
437432
InfrastructureRef: *infraRef,
438433
Bootstrap: clusterv1.Bootstrap{
439434
ConfigRef: bootstrapRef,

pkg/rke2/config.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ type ServerConfigOpts struct {
155155
AgentConfig bootstrapv1.RKE2AgentConfig
156156
Ctx context.Context
157157
Client client.Client
158+
Version string
158159
}
159160

160161
func newRKE2ServerConfig(opts ServerConfigOpts) (*rke2ServerConfig, []bootstrapv1.File, error) { // nolint:gocyclo
@@ -403,6 +404,7 @@ type AgentConfigOpts struct {
403404
Client client.Client
404405
CloudProviderName string
405406
CloudProviderConfigMap *corev1.ObjectReference
407+
Version string
406408
}
407409

408410
func newRKE2AgentConfig(opts AgentConfigOpts) (*rke2AgentConfig, []bootstrapv1.File, error) {
@@ -411,8 +413,8 @@ func newRKE2AgentConfig(opts AgentConfigOpts) (*rke2AgentConfig, []bootstrapv1.F
411413
rke2AgentConfig.ContainerRuntimeEndpoint = opts.AgentConfig.ContainerRuntimeEndpoint
412414

413415
if opts.AgentConfig.CISProfile != "" {
414-
if !bsutil.ProfileCompliant(opts.AgentConfig.CISProfile, opts.AgentConfig.Version) {
415-
return nil, nil, fmt.Errorf("profile %q is not supported for version %q", opts.AgentConfig.CISProfile, opts.AgentConfig.Version)
416+
if !bsutil.ProfileCompliant(opts.AgentConfig.CISProfile, opts.Version) {
417+
return nil, nil, fmt.Errorf("profile %q is not supported for version %q", opts.AgentConfig.CISProfile, opts.Version)
416418
}
417419

418420
files = append(files, bootstrapv1.File{
@@ -550,6 +552,7 @@ func GenerateInitControlPlaneConfig(opts ServerConfigOpts) (*rke2ServerConfig, [
550552
Client: opts.Client,
551553
Ctx: opts.Ctx,
552554
Token: opts.Token,
555+
Version: opts.Version,
553556
})
554557
if err != nil {
555558
return nil, nil, fmt.Errorf("failed to generate rke2 agent config: %w", err)
@@ -581,6 +584,7 @@ func GenerateJoinControlPlaneConfig(opts ServerConfigOpts) (*rke2ServerConfig, [
581584
Ctx: opts.Ctx,
582585
ServerURL: opts.ServerURL,
583586
Token: opts.Token,
587+
Version: opts.Version,
584588
})
585589
if err != nil {
586590
return nil, nil, fmt.Errorf("failed to generate rke2 agent config: %w", err)

pkg/rke2/config_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@ var _ = Describe("RKE2 Agent Config", func() {
295295
ExtraEnv: map[string]string{"testenv": "testenv"},
296296
ExtraMounts: map[string]string{"testmount": "testmount"},
297297
},
298-
Version: "v1.25.2",
299298
},
299+
Version: "v1.25.2",
300300
}
301301
})
302302

pkg/rke2/control_plane.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ func (c *ControlPlane) FailureDomains() clusterv1.FailureDomains {
116116

117117
// Version returns the RKE2ControlPlane's version.
118118
func (c *ControlPlane) Version() *string {
119-
return &c.RCP.Spec.AgentConfig.Version
119+
version := c.RCP.GetDesiredVersion()
120+
121+
return &version
120122
}
121123

122124
// InfrastructureRef returns the RKE2ControlPlane's infrastructure template.

pkg/rke2/machine_filters.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func matchesRCPConfiguration(
2222
rcp *controlplanev1.RKE2ControlPlane,
2323
) func(machine *clusterv1.Machine) bool {
2424
return collections.And(
25-
matchesKubernetesVersion(rcp.Spec.AgentConfig.Version),
25+
matchesKubernetesOrRKE2Version(rcp.GetDesiredVersion()),
2626
matchesRKE2BootstrapConfig(machineConfigs, rcp),
2727
matchesTemplateClonedFrom(infraConfigs, rcp),
2828
)
@@ -119,8 +119,8 @@ func matchesTemplateClonedFrom(infraConfigs map[string]*unstructured.Unstructure
119119
}
120120
}
121121

122-
// matchesKubernetesVersion returns a filter to find all machines that match a given Kubernetes version.
123-
func matchesKubernetesVersion(kubernetesVersion string) func(*clusterv1.Machine) bool {
122+
// matchesKubernetesVersion returns a filter to find all machines that match a given Kubernetes or RKE2 version.
123+
func matchesKubernetesOrRKE2Version(rke2Version string) func(*clusterv1.Machine) bool {
124124
return func(machine *clusterv1.Machine) bool {
125125
if machine == nil {
126126
return false
@@ -130,7 +130,11 @@ func matchesKubernetesVersion(kubernetesVersion string) func(*clusterv1.Machine)
130130
return false
131131
}
132132

133-
rcpKubeVersion, err := bsutil.Rke2ToKubeVersion(kubernetesVersion)
133+
if bsutil.IsRKE2Version(*machine.Spec.Version) {
134+
return bsutil.CompareVersions(*machine.Spec.Version, rke2Version)
135+
}
136+
137+
rcpKubeVersion, err := bsutil.Rke2ToKubeVersion(rke2Version)
134138
if err != nil {
135139
return true
136140
}

pkg/rke2/machine_filters_test.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import (
1414
controlplanev1 "github.com/rancher-sandbox/cluster-api-provider-rke2/controlplane/api/v1beta1"
1515
)
1616

17+
var (
18+
k8sMachineVersion = "v1.24.6"
19+
rke2MachineVersion = "v1.24.6+rke2r1"
20+
regionEuCentral1 = "eu-central-1"
21+
)
22+
1723
var rcp = controlplanev1.RKE2ControlPlane{
1824
ObjectMeta: v1.ObjectMeta{
1925
Name: "rke2-cluster-control-plane",
@@ -27,18 +33,13 @@ var rcp = controlplanev1.RKE2ControlPlane{
2733
},
2834
RKE2ConfigSpec: bootstrapv1.RKE2ConfigSpec{
2935
AgentConfig: bootstrapv1.RKE2AgentConfig{
30-
Version: "v1.24.6+rke2r1",
36+
Version: rke2MachineVersion,
3137
NodeLabels: []string{"hello=world"},
3238
},
3339
},
3440
},
3541
}
3642

37-
var (
38-
machineVersion = "v1.24.6"
39-
regionEuCentral1 = "eu-central-1"
40-
)
41-
4243
var machine = clusterv1.Machine{
4344
ObjectMeta: v1.ObjectMeta{
4445
Name: "machine-test",
@@ -49,7 +50,7 @@ var machine = clusterv1.Machine{
4950
},
5051
Spec: clusterv1.MachineSpec{
5152
ClusterName: "rke2-cluster",
52-
Version: &machineVersion,
53+
Version: &k8sMachineVersion,
5354
FailureDomain: &regionEuCentral1,
5455
Bootstrap: clusterv1.Bootstrap{
5556
ConfigRef: &corev1.ObjectReference{
@@ -80,7 +81,7 @@ var _ = Describe("matchAgentConfig", func() {
8081
},
8182
Spec: bootstrapv1.RKE2ConfigSpec{
8283
AgentConfig: bootstrapv1.RKE2AgentConfig{
83-
Version: "v1.24.6+rke2r1",
84+
Version: rke2MachineVersion,
8485
NodeLabels: []string{"hello=world"},
8586
},
8687
},
@@ -99,7 +100,15 @@ var _ = Describe("matchAgentConfig", func() {
99100
var _ = Describe("matching Kubernetes Version", func() {
100101
It("should match version", func() {
101102
machineCollection := collections.FromMachines(&machine)
102-
matches := machineCollection.AnyFilter(matchesKubernetesVersion(rcp.Spec.AgentConfig.Version))
103+
matches := machineCollection.AnyFilter(matchesKubernetesOrRKE2Version(rcp.GetDesiredVersion()))
104+
Expect(len(matches)).To(Equal(1))
105+
})
106+
107+
It("should match when RKE2 version is set on the machine", func() {
108+
machine.Spec.Version = &rke2MachineVersion
109+
machineCollection := collections.FromMachines(&machine)
110+
matches := machineCollection.AnyFilter(matchesKubernetesOrRKE2Version(rcp.GetDesiredVersion()))
103111
Expect(len(matches)).To(Equal(1))
112+
machine.Spec.Version = &k8sMachineVersion
104113
})
105114
})

0 commit comments

Comments
 (0)