Skip to content

Commit dc1051f

Browse files
authored
🐛 fix: considers objects in kube-system for cert-manager to avoid upgrading twice (#11351)
* fix: considers objects in kube-system for cert-manager to avoid upgrading twice * fix: removes use of slices.DeleteFunc because it zeros the elements and doesn't remove those from obj list * fix: do not reassign slice as it is used in different methods
1 parent ceab066 commit dc1051f

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

cmd/clusterctl/client/cluster/cert_manager.go

+21-12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/pkg/errors"
2626
corev1 "k8s.io/api/core/v1"
2727
apierrors "k8s.io/apimachinery/pkg/api/errors"
28+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2829
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2930
"sigs.k8s.io/controller-runtime/pkg/client"
3031

@@ -53,6 +54,10 @@ const (
5354
var (
5455
//go:embed assets/cert-manager-test-resources.yaml
5556
certManagerTestManifest []byte
57+
// namespaces for all relevant objects in a cert-manager installation.
58+
// It also includes relevant resources in the kube-system namespace, which is used by cert-manager
59+
// for leader election (https://github.com/cert-manager/cert-manager/issues/6716).
60+
certManagerNamespaces = []string{certManagerNamespace, metav1.NamespaceSystem}
5661
)
5762

5863
// CertManagerUpgradePlan defines the upgrade plan if cert-manager needs to be
@@ -202,9 +207,9 @@ func (cm *certManagerClient) install(ctx context.Context, version string, objs [
202207
func (cm *certManagerClient) PlanUpgrade(ctx context.Context) (CertManagerUpgradePlan, error) {
203208
log := logf.Log
204209

205-
objs, err := cm.proxy.ListResources(ctx, map[string]string{clusterctlv1.ClusterctlCoreLabel: clusterctlv1.ClusterctlCoreLabelCertManagerValue}, certManagerNamespace)
210+
objs, err := cm.proxy.ListResources(ctx, map[string]string{clusterctlv1.ClusterctlCoreLabel: clusterctlv1.ClusterctlCoreLabelCertManagerValue}, certManagerNamespaces...)
206211
if err != nil {
207-
return CertManagerUpgradePlan{}, errors.Wrap(err, "failed get cert manager components")
212+
return CertManagerUpgradePlan{}, errors.Wrap(err, "failed to get cert-manager components")
208213
}
209214

210215
// If there are no cert manager components with the clusterctl labels, it means that cert-manager is externally managed.
@@ -240,12 +245,10 @@ func (cm *certManagerClient) PlanUpgrade(ctx context.Context) (CertManagerUpgrad
240245
// older than the version currently suggested by clusterctl, upgrades it.
241246
func (cm *certManagerClient) EnsureLatestVersion(ctx context.Context) error {
242247
log := logf.Log
243-
244-
objs, err := cm.proxy.ListResources(ctx, map[string]string{clusterctlv1.ClusterctlCoreLabel: clusterctlv1.ClusterctlCoreLabelCertManagerValue}, certManagerNamespace)
248+
objs, err := cm.proxy.ListResources(ctx, map[string]string{clusterctlv1.ClusterctlCoreLabel: clusterctlv1.ClusterctlCoreLabelCertManagerValue}, certManagerNamespaces...)
245249
if err != nil {
246-
return errors.Wrap(err, "failed get cert manager components")
250+
return errors.Wrap(err, "failed to get cert-manager components")
247251
}
248-
249252
// If there are no cert manager components with the clusterctl labels, it means that cert-manager is externally managed.
250253
if len(objs) == 0 {
251254
log.V(5).Info("Skipping cert-manager upgrade because externally managed")
@@ -338,13 +341,19 @@ func (cm *certManagerClient) shouldUpgrade(desiredVersion string, objs, installO
338341

339342
needUpgrade := false
340343
currentVersion := ""
341-
for i := range objs {
342-
obj := objs[i]
343344

344-
// Endpoints and EndpointSlices are generated by Kubernetes without the version annotation, so we are skipping them
345-
if obj.GetKind() == "Endpoints" || obj.GetKind() == "EndpointSlice" {
346-
continue
345+
// creates a new list removing resources that are generated by the kubernetes API
346+
// this is relevant if the versions are the same, because we compare
347+
// the number of objects when version of objects are equal
348+
relevantObjs := []unstructured.Unstructured{}
349+
for _, o := range objs {
350+
if !(o.GetKind() == "Endpoints" || o.GetKind() == "EndpointSlice") {
351+
relevantObjs = append(relevantObjs, o)
347352
}
353+
}
354+
355+
for i := range relevantObjs {
356+
obj := relevantObjs[i]
348357

349358
// if there is no version annotation, this means the obj is cert-manager v0.11.0 (installed with older version of clusterctl)
350359
objVersion, ok := obj.GetAnnotations()[clusterctlv1.CertManagerVersionAnnotation]
@@ -374,7 +383,7 @@ func (cm *certManagerClient) shouldUpgrade(desiredVersion string, objs, installO
374383
// The installed version is equal to the desired version. Upgrade is required only if the number
375384
// of available objects and objects to install differ. This would act as a re-install.
376385
currentVersion = objVersion
377-
needUpgrade = len(objs) != len(installObjs)
386+
needUpgrade = len(relevantObjs) != len(installObjs)
378387
case c > 0:
379388
// The installed version is greater than the desired version. Upgrade is not required.
380389
currentVersion = objVersion

0 commit comments

Comments
 (0)