Skip to content

Commit

Permalink
backport clusterctl discovery fix
Browse files Browse the repository at this point in the history
This patch was originally introduced in PR #5684.
Original name: "clusterctl discovery should ignore provider's resources"
Original commit id: db5b183

Original description:

While managing components (for cert-manager or providers) clusterctl
implements a discovery function to seek for all the objects
part of the component.

This commit makes this code to ignore resources for a provider
(e.g Cluster for CAPI, AWSCluster for CAPA, Certificates for cert-manager)
given that those resources are not part of the component itself.

This will make operations like upgrade plan or apply and delete resilient to actual
state of cert-manager web hooks; in fact, those operations can now work when
web-hooks are not functioning (due to provider's deployment already deleted,
to provider scaled down to 0, to other errors)

This commit also introduces some logic originally implemented in commit
f5a9d76 that implements the ability to skip excluded CRD during
resource listing.

Reason for backporting:

The issues that were solved by commit db5b183 and f5a9d76  on the main
branch are also effecting older releases of CAPI currently in use thus backporting
the "discovery fix" and some related code from f5a9d76 would solve a lot of issue
faced by users e.g related to upgrade process as mentioned in the original db5b183 commit.
  • Loading branch information
fabriziopandini authored and Rozzii committed Nov 20, 2021
1 parent 75ddb72 commit 8f14e04
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions cmd/clusterctl/client/cluster/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@ import (
"time"

"github.com/pkg/errors"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
utilversion "k8s.io/apimachinery/pkg/util/version"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
"sigs.k8s.io/cluster-api/cmd/clusterctl/internal/scheme"
"sigs.k8s.io/cluster-api/version"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -171,6 +176,30 @@ func (k *proxy) ListResources(labels map[string]string, namespaces ...string) ([
return nil, errors.Wrap(err, "failed to list api resources")
}

// Exclude from discovery the objects from the cert-manager/provider's CRDs.
// Those objects are not part of the components, and they will eventually be removed when removing the CRD definition.
crdsToExclude := sets.String{}

crdList := &apiextensionsv1.CustomResourceDefinitionList{}
if err := retryWithExponentialBackoff(newReadBackoff(), func() error {
return c.List(ctx, crdList)
}); err != nil {
return nil, errors.Wrap(err, "failed to list CRDs")
}
for _, crd := range crdList.Items {
component, isCoreComponent := labels[clusterctlv1.ClusterctlCoreLabelName]
_, isProviderResource := crd.Labels[clusterv1.ProviderLabelName]
if (isCoreComponent && component == clusterctlv1.ClusterctlCoreLabelCertManagerValue) || isProviderResource {
for _, version := range crd.Spec.Versions {
crdsToExclude.Insert(metav1.GroupVersionKind{
Group: crd.Spec.Group,
Version: version.Name,
Kind: crd.Spec.Names.Kind,
}.String())
}
}
}

// Select resources with list and delete methods (list is required by this method, delete by the callers of this method)
resourceList = discovery.FilteredBy(discovery.SupportsAllVerbs{Verbs: []string{"list", "delete"}}, resourceList)

Expand All @@ -183,6 +212,20 @@ func (k *proxy) ListResources(labels map[string]string, namespaces ...string) ([
continue
}

// Continue if the resource is an excluded CRD.
gv, err := schema.ParseGroupVersion(resourceGroup.GroupVersion)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse GroupVersion")
}
if crdsToExclude.Has(metav1.GroupVersionKind{
Group: gv.Group,
Version: gv.Version,
Kind: resourceKind.Kind,
}.String()) {
continue
}


// List all the object instances of this resourceKind with the given labels
if resourceKind.Namespaced {
for _, namespace := range namespaces {
Expand Down

0 comments on commit 8f14e04

Please sign in to comment.