From 6394dadbefb138af9ffd8d20bc57a6a070d09515 Mon Sep 17 00:00:00 2001 From: Pankti Shah <58618433+panktishah26@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:16:21 -0800 Subject: [PATCH] Make Ubuntu a default OS for tinkerbell and add validation for 1.29 k8s version for BR family (#7655) --- .../tinkerbelldatacenterconfig_types.go | 2 +- pkg/api/v1alpha1/tinkerbellmachineconfig.go | 2 +- pkg/providers/tinkerbell/assert_test.go | 34 +++++++++++++++++++ pkg/providers/tinkerbell/validate.go | 25 ++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/pkg/api/v1alpha1/tinkerbelldatacenterconfig_types.go b/pkg/api/v1alpha1/tinkerbelldatacenterconfig_types.go index 23747b292ae5..d2d8af8c4aab 100644 --- a/pkg/api/v1alpha1/tinkerbelldatacenterconfig_types.go +++ b/pkg/api/v1alpha1/tinkerbelldatacenterconfig_types.go @@ -18,7 +18,7 @@ type TinkerbellDatacenterConfigSpec struct { // It must include the Kubernetes version(s). For example, a URL used for Kubernetes 1.27 could // be http://localhost:8080/ubuntu-2204-1.27.tgz //+optional - OSImageURL string `json:"osImageURL,omitempty"` + OSImageURL string `json:"osImageURL"` // HookImagesURLPath can be used to override the default Hook images path to pull from a local server. HookImagesURLPath string `json:"hookImagesURLPath,omitempty"` // SkipLoadBalancerDeployment when set to "true" can be used to skip deploying a load balancer to expose Tinkerbell stack. diff --git a/pkg/api/v1alpha1/tinkerbellmachineconfig.go b/pkg/api/v1alpha1/tinkerbellmachineconfig.go index da3cdac9c32f..6caf77e7ea0b 100644 --- a/pkg/api/v1alpha1/tinkerbellmachineconfig.go +++ b/pkg/api/v1alpha1/tinkerbellmachineconfig.go @@ -26,7 +26,7 @@ func NewTinkerbellMachineConfigGenerate(name string, opts ...TinkerbellMachineCo }, Spec: TinkerbellMachineConfigSpec{ HardwareSelector: HardwareSelector{}, - OSFamily: Bottlerocket, + OSFamily: Ubuntu, Users: []UserConfiguration{ { Name: "ec2-user", diff --git a/pkg/providers/tinkerbell/assert_test.go b/pkg/providers/tinkerbell/assert_test.go index db25bbf9ebad..c306360a90e0 100644 --- a/pkg/providers/tinkerbell/assert_test.go +++ b/pkg/providers/tinkerbell/assert_test.go @@ -121,6 +121,40 @@ func TestAssertMachineConfigNamespaceMatchesDatacenterConfig_Different(t *testin g.Expect(err).ToNot(gomega.Succeed()) } +func TestAssertMachineConfigK8sVersionBRCP_Error(t *testing.T) { + g := gomega.NewWithT(t) + builder := NewDefaultValidClusterSpecBuilder() + clusterSpec := builder.Build() + clusterSpec.Spec.Cluster.Spec.ExternalEtcdConfiguration = nil + clusterSpec.Spec.Cluster.Spec.KubernetesVersion = eksav1alpha1.Kube129 + clusterSpec.MachineConfigs[builder.ControlPlaneMachineName].Spec.OSFamily = "bottlerocket" + err := tinkerbell.AssertOsFamilyValid(clusterSpec) + g.Expect(err).ToNot(gomega.Succeed()) +} + +func TestAssertMachineConfigK8sVersionBRWorker_Error(t *testing.T) { + g := gomega.NewWithT(t) + builder := NewDefaultValidClusterSpecBuilder() + clusterSpec := builder.Build() + clusterSpec.Spec.Cluster.Spec.ExternalEtcdConfiguration = nil + clusterSpec.Spec.Cluster.Spec.KubernetesVersion = eksav1alpha1.Kube129 + clusterSpec.MachineConfigs[builder.WorkerNodeGroupMachineName].Spec.OSFamily = "bottlerocket" + err := tinkerbell.AssertOsFamilyValid(clusterSpec) + g.Expect(err).ToNot(gomega.Succeed()) +} + +func TestAssertMachineConfigK8sVersionBR_Success(t *testing.T) { + g := gomega.NewWithT(t) + builder := NewDefaultValidClusterSpecBuilder() + clusterSpec := builder.Build() + clusterSpec.Spec.Cluster.Spec.ExternalEtcdConfiguration = nil + clusterSpec.Spec.Cluster.Spec.KubernetesVersion = eksav1alpha1.Kube128 + clusterSpec.MachineConfigs[builder.ControlPlaneMachineName].Spec.OSFamily = "bottlerocket" + clusterSpec.MachineConfigs[builder.WorkerNodeGroupMachineName].Spec.OSFamily = "bottlerocket" + err := tinkerbell.AssertOsFamilyValid(clusterSpec) + g.Expect(err).To(gomega.Succeed()) +} + func TestAssertMachineConfigOSImageURL_Error(t *testing.T) { g := gomega.NewWithT(t) builder := NewDefaultValidClusterSpecBuilder() diff --git a/pkg/providers/tinkerbell/validate.go b/pkg/providers/tinkerbell/validate.go index a79efcaafeaa..6a956f0235aa 100644 --- a/pkg/providers/tinkerbell/validate.go +++ b/pkg/providers/tinkerbell/validate.go @@ -10,6 +10,7 @@ import ( "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/networkutils" "github.com/aws/eks-anywhere/pkg/providers/tinkerbell/hardware" + "github.com/aws/eks-anywhere/pkg/semver" ) func validateOsFamily(spec *ClusterSpec) error { @@ -23,11 +24,22 @@ func validateOsFamily(spec *ClusterSpec) error { } } + if controlPlaneOsFamily == v1alpha1.Bottlerocket { + if err := validateK8sVersionForBottleRocketOS(string(spec.Cluster.Spec.KubernetesVersion)); err != nil { + return fmt.Errorf("machineGroupRef %s: %v", controlPlaneRef.Name, err) + } + } + for _, group := range spec.Cluster.Spec.WorkerNodeGroupConfigurations { groupRef := group.MachineGroupRef if spec.MachineConfigs[groupRef.Name].OSFamily() != controlPlaneOsFamily { return errors.New("worker node group osFamily cannot be different from control plane osFamily") } + if group.KubernetesVersion != nil && *group.KubernetesVersion != "" && spec.MachineConfigs[groupRef.Name].OSFamily() == v1alpha1.Bottlerocket { + if err := validateK8sVersionForBottleRocketOS(string(*group.KubernetesVersion)); err != nil { + return fmt.Errorf("machineGroupRef %s: %v", groupRef.Name, err) + } + } } if controlPlaneOsFamily != v1alpha1.Bottlerocket && spec.DatacenterConfig.Spec.OSImageURL == "" && spec.ControlPlaneMachineConfig().Spec.OSImageURL == "" { @@ -37,6 +49,19 @@ func validateOsFamily(spec *ClusterSpec) error { return nil } +func validateK8sVersionForBottleRocketOS(kubernetesVersion string) error { + kubeVersionSemver, err := semver.New(kubernetesVersion + ".0") + if err != nil { + return fmt.Errorf("converting kubeVersion %v to semver %v", kubernetesVersion, err) + } + + kube128Semver, _ := semver.New(string(v1alpha1.Kube128) + ".0") + if kubeVersionSemver.GreaterThan(kube128Semver) { + return errors.New("tinkerbell provider does not support K8s version 1.29+ for BottleRocket OS") + } + return nil +} + func validateUpgradeRolloutStrategy(spec *ClusterSpec) error { cpUpgradeRolloutStrategyType := v1alpha1.RollingUpdateStrategyType