From 23ace87eb39e977cdb6186af2de1897b9457c33f Mon Sep 17 00:00:00 2001 From: justinsb Date: Wed, 25 Oct 2023 09:40:51 -0400 Subject: [PATCH] Add validation to help users move from experimentClusterSigningDuration We aren't aiming to do this in general, but if we can easily help users find the new option for deprecated flags, that will save everyone time. Issue #15909 --- pkg/apis/kops/validation/validation.go | 18 +++++++ pkg/apis/kops/validation/validation_test.go | 60 +++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/pkg/apis/kops/validation/validation.go b/pkg/apis/kops/validation/validation.go index c1b161334595c..af2b5c6f0db6d 100644 --- a/pkg/apis/kops/validation/validation.go +++ b/pkg/apis/kops/validation/validation.go @@ -130,6 +130,10 @@ func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *fie allErrs = append(allErrs, validateKubeAPIServer(spec.KubeAPIServer, c, fieldPath.Child("kubeAPIServer"), strict)...) } + if spec.KubeControllerManager != nil { + allErrs = append(allErrs, validateKubeControllerManager(spec.KubeControllerManager, c, fieldPath.Child("kubeControllerManager"), strict)...) + } + if spec.KubeProxy != nil { allErrs = append(allErrs, validateKubeProxy(spec.KubeProxy, fieldPath.Child("kubeProxy"))...) } @@ -824,6 +828,20 @@ func validateKubeAPIServer(v *kops.KubeAPIServerConfig, c *kops.Cluster, fldPath return allErrs } +func validateKubeControllerManager(v *kops.KubeControllerManagerConfig, c *kops.Cluster, fldPath *field.Path, strict bool) field.ErrorList { + allErrs := field.ErrorList{} + + // We aren't aiming to do comprehensive validation, but we can add some best-effort validation where it helps guide users + // Users reported encountered this in #15909 + if v.ExperimentalClusterSigningDuration != nil { + if c.IsKubernetesGTE("1.25") { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("experimentalClusterSigningDuration"), "experimentalClusterSigningDuration has been replaced with clusterSigningDuration as of kubernetes 1.25")) + } + } + + return allErrs +} + func validateKubeProxy(k *kops.KubeProxyConfig, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} diff --git a/pkg/apis/kops/validation/validation_test.go b/pkg/apis/kops/validation/validation_test.go index 279c86f7f9ab0..278742a57b10e 100644 --- a/pkg/apis/kops/validation/validation_test.go +++ b/pkg/apis/kops/validation/validation_test.go @@ -19,7 +19,9 @@ package validation import ( "net" "testing" + "time" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" @@ -339,6 +341,64 @@ func TestValidateKubeAPIServer(t *testing.T) { } } +func TestValidateKubeControllermanager(t *testing.T) { + grid := []struct { + Input kops.KubeControllerManagerConfig + Cluster *kops.Cluster + ExpectedErrors []string + ExpectedDetail string + }{ + { + Input: kops.KubeControllerManagerConfig{ + ExperimentalClusterSigningDuration: &metav1.Duration{Duration: time.Hour}, + }, + ExpectedErrors: []string{ + "Forbidden::kubeControllerManager.experimentalClusterSigningDuration", + }, + ExpectedDetail: "experimentalClusterSigningDuration has been replaced with clusterSigningDuration as of kubernetes 1.25", + }, + { + Input: kops.KubeControllerManagerConfig{ + ExperimentalClusterSigningDuration: &metav1.Duration{Duration: time.Hour}, + }, + Cluster: &kops.Cluster{ + Spec: kops.ClusterSpec{ + KubernetesVersion: "1.24.0", + }, + }, + ExpectedErrors: []string{}, + }, + } + for _, g := range grid { + if g.Cluster == nil { + g.Cluster = &kops.Cluster{ + Spec: kops.ClusterSpec{ + KubernetesVersion: "1.28.0", + }, + } + } + errs := validateKubeControllerManager(&g.Input, g.Cluster, field.NewPath("kubeControllerManager"), true) + + testErrors(t, g.Input, errs, g.ExpectedErrors) + + if g.ExpectedDetail != "" { + found := false + for _, err := range errs { + if err.Detail == g.ExpectedDetail { + found = true + } + } + if !found { + for _, err := range errs { + t.Logf("found detail: %q", err.Detail) + } + + t.Errorf("did not find expected error %q", g.ExpectedDetail) + } + } + } +} + func Test_Validate_Networking_Flannel(t *testing.T) { grid := []struct { Input kops.FlannelNetworkingSpec