Skip to content

Commit

Permalink
add webhook validation
Browse files Browse the repository at this point in the history
  • Loading branch information
sbueringer committed Jan 4, 2023
1 parent 7bd38a2 commit 9da8b5b
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 43 deletions.
16 changes: 16 additions & 0 deletions controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"

bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
"sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/util/kubeadm"
"sigs.k8s.io/cluster-api/util/container"
"sigs.k8s.io/cluster-api/util/version"
)
Expand Down Expand Up @@ -616,6 +617,21 @@ func (in *KubeadmControlPlane) validateVersion(previousVersion string) (allErrs
)
}

if in.Spec.KubeadmConfigSpec.ClusterConfiguration != nil &&
in.Spec.KubeadmConfigSpec.ClusterConfiguration.ImageRepository == "" {
if toVersion.GTE(kubeadm.MinKubernetesVersionImageRegistryMigration) &&
toVersion.LT(kubeadm.NextKubernetesVersionImageRegistryMigration) {
if kubeadm.GetDefaultRegistry(toVersion) == kubeadm.OldKubernetesImageRepository {
allErrs = append(allErrs,
field.Forbidden(
field.NewPath("spec", "version"),
fmt.Sprintf("cannot upgrade to a Kubernetes (kubeadm) version which is using the old default registry. Please use a newer Kubernetes patch release which is using the new default registry (>= v1.22.17, >= v1.23.15, >= v1.24.9"),
),
)
}
}
}

return allErrs
}

Expand Down
71 changes: 71 additions & 0 deletions controlplane/kubeadm/internal/util/kubeadm/kubeadm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package kubeadm

import "github.com/blang/semver"

const (
// KubernetesImageRepository is the new default Kubernetes image registry.
KubernetesImageRepository = "registry.k8s.io"
// OldKubernetesImageRepository is the old default Kubernetes image registry.
OldKubernetesImageRepository = "k8s.gcr.io"
)

var (
// MinKubernetesVersionImageRegistryMigration is the first Kubernetes minor version which
// has patch versions where the default image registry in kubeadm is registry.k8s.io instead of k8s.gcr.io.
MinKubernetesVersionImageRegistryMigration = semver.MustParse("1.22.0")

// NextKubernetesVersionImageRegistryMigration is the next minor version after
// the default image registry in kubeadm changed to registry.k8s.io.
NextKubernetesVersionImageRegistryMigration = semver.MustParse("1.26.0")
)

func GetDefaultRegistry(version semver.Version) string {

// If version <= v1.22.16 return k8s.gcr.io
if version.LTE(semver.MustParse("1.22.16")) {
return OldKubernetesImageRepository
}

// If v1.22.17 <= version < v1.23.0 return registry.k8s.io
if version.GTE(semver.MustParse("1.22.17")) &&
version.LT(semver.MustParse("1.23.0")) {
return KubernetesImageRepository
}

// If v1.23.0 <= version <= v1.23.14 return k8s.gcr.io
if version.GTE(semver.MustParse("1.23.0")) &&
version.LTE(semver.MustParse("1.23.14")) {
return OldKubernetesImageRepository
}

// If v1.23.15 <= version < v1.24.0 return registry.k8s.io
if version.GTE(semver.MustParse("1.23.15")) &&
version.LT(semver.MustParse("1.24.0")) {
return KubernetesImageRepository
}

// If v1.24.0 <= version <= v1.24.8 return k8s.gcr.io
if version.GTE(semver.MustParse("1.24.0")) &&
version.LTE(semver.MustParse("1.24.8")) {
return OldKubernetesImageRepository
}

// If v1.24.9 <= version return registry.k8s.io
return KubernetesImageRepository
}
40 changes: 6 additions & 34 deletions controlplane/kubeadm/internal/workload_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
kubeadmtypes "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types"
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
"sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/proxy"
"sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/util/kubeadm"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/certs"
containerutil "sigs.k8s.io/cluster-api/util/container"
Expand Down Expand Up @@ -632,40 +633,11 @@ func ImageRepositoryFromClusterConfig(clusterConfig *bootstrapv1.ClusterConfigur
return clusterConfig.ImageRepository
}

// If v1.22.0 <= version <= v1.22.16 return k8s.gcr.io
if kubernetesVersion.GTE(semver.MustParse("1.22.0")) &&
kubernetesVersion.LTE(semver.MustParse("1.22.6")) {
return oldKubernetesImageRepository
}

// If v1.22.17 <= version < v1.23.0 return registry.k8s.io
if kubernetesVersion.GTE(semver.MustParse("1.22.17")) &&
kubernetesVersion.LT(semver.MustParse("1.23.0")) {
return kubernetesImageRepository
}

// If v1.23.0 <= version <= v1.23.14 return k8s.gcr.io
if kubernetesVersion.GTE(semver.MustParse("1.23.0")) &&
kubernetesVersion.LTE(semver.MustParse("1.23.14")) {
return oldKubernetesImageRepository
}

// If v1.23.15 <= version < v1.24.0 return registry.k8s.io
if kubernetesVersion.GTE(semver.MustParse("1.23.15")) &&
kubernetesVersion.LT(semver.MustParse("1.24.0")) {
return kubernetesImageRepository
}

// If v1.24.0 <= version <= v1.24.8 return k8s.gcr.io
if kubernetesVersion.GTE(semver.MustParse("1.24.0")) &&
kubernetesVersion.LTE(semver.MustParse("1.24.8")) {
return oldKubernetesImageRepository
}

// If v1.24.9 <= version < v1.26.0 return registry.k8s.io
if kubernetesVersion.GTE(semver.MustParse("1.24.9")) &&
kubernetesVersion.LT(semver.MustParse("1.26.0")) {
return kubernetesImageRepository
// If v1.22.0 <= version < v1.26.0 return the default registry of the
// corresponding kubeadm binary.
if kubernetesVersion.GTE(kubeadm.MinKubernetesVersionImageRegistryMigration) &&
kubernetesVersion.LT(kubeadm.NextKubernetesVersionImageRegistryMigration) {
return kubeadm.GetDefaultRegistry(kubernetesVersion)
}

// Use defaulting or current values otherwise.
Expand Down
16 changes: 7 additions & 9 deletions controlplane/kubeadm/internal/workload_cluster_coredns.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (

bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
"sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/util/kubeadm"
containerutil "sigs.k8s.io/cluster-api/util/container"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/cluster-api/util/version"
Expand All @@ -47,11 +48,8 @@ const (
coreDNSVolumeKey = "config-volume"
coreDNSClusterRoleName = "system:coredns"

// kubernetesImageRepository is the default Kubernetes image repository for build artifacts.
kubernetesImageRepository = "registry.k8s.io"
oldKubernetesImageRepository = "k8s.gcr.io"
oldCoreDNSImageName = "coredns"
coreDNSImageName = "coredns/coredns"
oldCoreDNSImageName = "coredns"
coreDNSImageName = "coredns/coredns"

oldControlPlaneTaint = "node-role.kubernetes.io/master" // Deprecated: https://github.com/kubernetes/kubeadm/issues/2200
controlPlaneTaint = "node-role.kubernetes.io/control-plane"
Expand Down Expand Up @@ -200,11 +198,11 @@ func (w *Workload) getCoreDNSInfo(ctx context.Context, clusterConfig *bootstrapv
toImageRepository := parsedImage.Repository
// Overwrite the image repository if a value was explicitly set or an upgrade is required.
if imageRegistryRepository := ImageRepositoryFromClusterConfig(clusterConfig, version); imageRegistryRepository != "" {
if imageRegistryRepository == kubernetesImageRepository {
if imageRegistryRepository == kubeadm.KubernetesImageRepository {
// Only patch to KubernetesImageRepository if oldKubernetesImageRepository is set as prefix.
if strings.HasPrefix(toImageRepository, oldKubernetesImageRepository) {
if strings.HasPrefix(toImageRepository, kubeadm.OldKubernetesImageRepository) {
// Ensure to keep the repository subpaths when patching from oldKubernetesImageRepository to new KubernetesImageRepository.
toImageRepository = strings.TrimSuffix(imageRegistryRepository+strings.TrimPrefix(toImageRepository, oldKubernetesImageRepository), "/")
toImageRepository = strings.TrimSuffix(imageRegistryRepository+strings.TrimPrefix(toImageRepository, kubeadm.OldKubernetesImageRepository), "/")
}
} else {
toImageRepository = strings.TrimSuffix(imageRegistryRepository, "/")
Expand Down Expand Up @@ -235,7 +233,7 @@ func (w *Workload) getCoreDNSInfo(ctx context.Context, clusterConfig *bootstrapv
// * "registry.k8s.io/coredns" to "registry.k8s.io/coredns/coredns" or
// * "k8s.gcr.io/coredns" to "k8s.gcr.io/coredns/coredns"
toImageName := parsedImage.Name
if (toImageRepository == oldKubernetesImageRepository || toImageRepository == kubernetesImageRepository) &&
if (toImageRepository == kubeadm.OldKubernetesImageRepository || toImageRepository == kubeadm.KubernetesImageRepository) &&
toImageName == oldCoreDNSImageName && targetMajorMinorPatch.GTE(semver.MustParse("1.8.0")) {
toImageName = coreDNSImageName
}
Expand Down

0 comments on commit 9da8b5b

Please sign in to comment.