kubernetes-sigs/cluster-api

clusterctl: Not able to remove cluster wide objects when provider deleted

Open

#12,592 opened on Aug 7, 2025

View on GitHub
 (6 comments) (0 reactions) (1 assignee)Go (1,532 forks)auto 404
area/clusterctlhelp wantedkind/bugpriority/backlogtriage/accepted

Repository metrics

Stars
 (4,267 stars)
PR merge metrics
 (PR metrics pending)

Description

What steps did you take and what happened?

For one of the scenarios, I need to install a cluster AIP provider, and then delete all its components except CRD and namespace.

I first ran clusterctl init, and then clusterctl delete. After that, I looked at the cluster and saw that there was some cluster wide resources left from my provider.

What did you expect to happen?

I expected that all objects in the cluster that have labels related to my provider would be deleted except the CRD and namespace.

This is example for Cluster API Provider vSphere, but it can be reproduced for any provider or addon:

kubectl --kubeconfig mytest-kubeconfig get clusterrole -l cluster.x-k8s.io/provider=infrastructure-vsphere
NAME                           CREATED AT
capv-aggregated-manager-role   2025-08-01T14:15:36Z
capv-manager-role              2025-08-01T14:15:36Z

kubectl --kubeconfig mytest-kubeconfig get all -n capv-system 
No resources found in capv-system namespace

Cluster API version

v1.9.10

Kubernetes version

v1.30.7

Anything else you would like to add?

I carefully studied the code below and read the threads it refers to:

		// If the resource is a cluster resource, skip it if the resource name does not start with the instance prefix.
		// This is required because there are cluster resources like e.g. ClusterRoles and ClusterRoleBinding, which are instance specific;
		// During the installation, clusterctl adds the instance namespace prefix to such resources (see fixRBAC), and so we can rely
		// on that for deleting only the global resources belonging the instance we are processing.
		// NOTE: namespace and CRD are special case managed above; webhook instead goes hand by hand with the controller they
		// should always be deleted.
		isWebhook := obj.GroupVersionKind().Kind == validatingWebhookConfigurationKind || obj.GroupVersionKind().Kind == mutatingWebhookConfigurationKind

		if util.IsClusterResource(obj.GetKind()) &&
			!isNamespace && !isCRD && !isWebhook &&
			// TODO(oscr) Delete the check below condition when the min version to upgrade from is CAPI v1.3
			// This check is needed due to the (now removed) support for multiple instances of the same provider.
			// For more context read GitHub issue #7318 and/or PR #7339
			!strings.HasPrefix(obj.GetName(), instanceNamespacePrefix) {
			continue
		}

To keep this code as is, it would be nice to add a separate delete flag which will be able to remove cluster-wide provider objects when its set to true whenever objects has specific prefix or not.

Label(s) to be applied

/kind bug One or more /area label. See https://github.com/kubernetes-sigs/cluster-api/labels?q=area for the list of labels. /area clusterctl

Contributor guide