diff --git a/cmd/clusterctl/test/e2e/go.sum b/cmd/clusterctl/test/e2e/go.sum index 16aa1469e38e..1bf478aef98e 100644 --- a/cmd/clusterctl/test/e2e/go.sum +++ b/cmd/clusterctl/test/e2e/go.sum @@ -40,6 +40,7 @@ github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/caddyserver/caddy v1.0.3 h1:i9gRhBgvc5ifchwWtSe7pDpsdS9+Q0Rw9oYQmYUTw1w= github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -50,7 +51,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/coredns/corefile-migration v1.0.6/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= +github.com/coredns/corefile-migration v1.0.7 h1:T2eOj/NKN1Q1W1bD9MFeZiBYryS0JlWT6aROAvVWFSs= +github.com/coredns/corefile-migration v1.0.7/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= diff --git a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go index 79aea2a1298e..9cd602cf787a 100644 --- a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go +++ b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go @@ -19,6 +19,8 @@ package v1alpha3 import ( "encoding/json" "fmt" + "github.com/coredns/corefile-migration/migration" + kubeadmv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1" "strings" "github.com/blang/semver" @@ -127,6 +129,7 @@ func (in *KubeadmControlPlane) ValidateUpdate(old runtime.Object) error { } allErrs = append(allErrs, in.validateEtcd(prev)...) + allErrs = append(allErrs, in.validateCoreDNSVersion(prev)...) if len(allErrs) > 0 { return apierrors.NewInvalid(GroupVersion.WithKind("KubeadmControlPlane").GroupKind(), in.Name, allErrs) @@ -237,12 +240,12 @@ func (in *KubeadmControlPlane) validateCommon() (allErrs field.ErrorList) { allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "version"), in.Spec.Version, "must be a valid semantic version")) } - allErrs = append(allErrs, in.validateCoreDNS()...) + allErrs = append(allErrs, in.validateCoreDNSImage()...) return allErrs } -func (in *KubeadmControlPlane) validateCoreDNS() (allErrs field.ErrorList) { +func (in *KubeadmControlPlane) validateCoreDNSImage() (allErrs field.ErrorList) { if in.Spec.KubeadmConfigSpec.ClusterConfiguration == nil { return allErrs } @@ -259,6 +262,55 @@ func (in *KubeadmControlPlane) validateCoreDNS() (allErrs field.ErrorList) { return allErrs } +func (in *KubeadmControlPlane) validateCoreDNSVersion(prev *KubeadmControlPlane) (allErrs field.ErrorList) { + if in.Spec.KubeadmConfigSpec.ClusterConfiguration == nil || prev.Spec.KubeadmConfigSpec.ClusterConfiguration == nil { + return allErrs + } + if prev.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS.ImageTag == "" { + return allErrs + } + dns := &in.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS + //return if the type is anything other than empty (default), or CoreDNS. + if dns.Type != "" && dns.Type != kubeadmv1.CoreDNS { + return allErrs + } + + fromVersion, err := util.ParseMajorMinorPatch(prev.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS.ImageTag) + if err != nil { + allErrs = append(allErrs, + field.InternalError( + field.NewPath("spec", "kubeadmConfigSpec", "clusterConfiguration", "dns", "imageTag"), + fmt.Errorf("failed to parse CoreDNS current version: %v", prev.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS.ImageTag), + ), + ) + return allErrs + } + + toVersion, err := util.ParseMajorMinorPatch(dns.ImageTag) + if err != nil { + allErrs = append(allErrs, + field.Invalid( + field.NewPath("spec", "kubeadmConfigSpec", "clusterConfiguration", "dns", "imageTag"), + dns.ImageTag, + fmt.Sprintf("failed to parse CoreDNS target version: %v", dns.ImageTag), + ), + ) + return allErrs + } + + if err := migration.ValidUpMigration(fromVersion.String(), toVersion.String()); err != nil { + allErrs = append( + allErrs, + field.Forbidden( + field.NewPath("spec", "kubeadmConfigSpec", "clusterConfiguration", "dns", "imageTag"), + fmt.Sprintf("cannot migrate CoreDNS up to '%v' from '%v'", toVersion, fromVersion), + ), + ) + } + + return allErrs +} + func (in *KubeadmControlPlane) validateEtcd(prev *KubeadmControlPlane) (allErrs field.ErrorList) { if in.Spec.KubeadmConfigSpec.ClusterConfiguration == nil { return allErrs diff --git a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go index 9c2a8ae8b651..70bc527c3169 100644 --- a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go +++ b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go @@ -175,6 +175,12 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { }, ClusterConfiguration: &kubeadmv1beta1.ClusterConfiguration{ ClusterName: "test", + DNS: kubeadmv1beta1.DNS{ + ImageMeta: kubeadmv1beta1.ImageMeta{ + ImageRepository: "k8s.gcr.io/coredns", + ImageTag: "1.6.5", + }, + }, }, JoinConfiguration: &kubeadmv1beta1.JoinConfiguration{ NodeRegistration: kubeadmv1beta1.NodeRegistrationOptions{ @@ -267,7 +273,7 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { dns.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS = kubeadmv1beta1.DNS{ ImageMeta: kubeadmv1beta1.ImageMeta{ ImageRepository: "gcr.io/capi-test", - ImageTag: "v0.20.0", + ImageTag: "v1.6.6_foobar.1", }, } @@ -275,7 +281,7 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { dnsBuildTag.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS = kubeadmv1beta1.DNS{ ImageMeta: kubeadmv1beta1.ImageMeta{ ImageRepository: "gcr.io/capi-test", - ImageTag: "v0.20.0_build1", + ImageTag: "1.6.7", }, } @@ -287,6 +293,22 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { }, } + dnsInvalidCoreDNSToVersion := dns.DeepCopy() + dnsInvalidCoreDNSToVersion.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS = kubeadmv1beta1.DNS{ + ImageMeta: kubeadmv1beta1.ImageMeta{ + ImageRepository: "gcr.io/capi-test", + ImageTag: "1.6.5", + }, + } + + validCoreDNSCustomToVersion := dns.DeepCopy() + validCoreDNSCustomToVersion.Spec.KubeadmConfigSpec.ClusterConfiguration.DNS = kubeadmv1beta1.DNS{ + ImageMeta: kubeadmv1beta1.ImageMeta{ + ImageRepository: "gcr.io/capi-test", + ImageTag: "v1.6.6_foobar.2", + }, + } + certificatesDir := before.DeepCopy() certificatesDir.Spec.KubeadmConfigSpec.ClusterConfiguration.CertificatesDir = "a new certificates directory" @@ -477,6 +499,12 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { before: before, kcp: dns, }, + { + name: "should succeed when changing to a valid custom CoreDNS version", + expectErr: false, + before: dns, + kcp: validCoreDNSCustomToVersion, + }, { name: "should succeed when using an valid DNS build", expectErr: false, @@ -489,6 +517,12 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { before: before, kcp: dnsInvalidTag, }, + { + name: "should fail when using an invalid CoreDNS version", + expectErr: true, + before: dns, + kcp: dnsInvalidCoreDNSToVersion, + }, { name: "should fail when making a change to the cluster config's certificatesDir", expectErr: true, diff --git a/go.mod b/go.mod index 6f4a96704872..4497325abb18 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.13 require ( github.com/MakeNowJust/heredoc v1.0.0 github.com/blang/semver v3.5.1+incompatible - github.com/coredns/corefile-migration v1.0.6 + github.com/coredns/corefile-migration v1.0.7 github.com/davecgh/go-spew v1.1.1 github.com/docker/distribution v2.7.1+incompatible github.com/evanphx/json-patch v4.5.0+incompatible diff --git a/go.sum b/go.sum index e31542b5c8ef..d2f4650ece90 100644 --- a/go.sum +++ b/go.sum @@ -53,8 +53,8 @@ github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlR github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/coredns/corefile-migration v1.0.6 h1:hB6vclp2g/KeXe9n1oz/PafgieUahsOYeHMQA+RJ4Hg= -github.com/coredns/corefile-migration v1.0.6/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= +github.com/coredns/corefile-migration v1.0.7 h1:T2eOj/NKN1Q1W1bD9MFeZiBYryS0JlWT6aROAvVWFSs= +github.com/coredns/corefile-migration v1.0.7/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= diff --git a/test/infrastructure/docker/go.sum b/test/infrastructure/docker/go.sum index 62f57e2de9df..72691bc258d0 100644 --- a/test/infrastructure/docker/go.sum +++ b/test/infrastructure/docker/go.sum @@ -41,6 +41,7 @@ github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/caddyserver/caddy v1.0.3 h1:i9gRhBgvc5ifchwWtSe7pDpsdS9+Q0Rw9oYQmYUTw1w= github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -51,7 +52,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/coredns/corefile-migration v1.0.6/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= +github.com/coredns/corefile-migration v1.0.7 h1:T2eOj/NKN1Q1W1bD9MFeZiBYryS0JlWT6aROAvVWFSs= +github.com/coredns/corefile-migration v1.0.7/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=