Repository: kubernetes-sigs/cluster-api
Pull request #8234 (2023-03-06 18:09:10)

:book: Fix v1alpha4 references in clusterctl comments
Fix up a couple of references to v1alpha4 in the clusterctl code.

Fixes #




k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
**Once this PR has been reviewed and has the lgtm label**, please ask for approval from killianmuldoon. For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api).

<details open>
Needs approval from an approver in each of these files:

- **[cmd/clusterctl/OWNERS](https://github.com/kubernetes-sigs/cluster-api/blob/main/cmd/clusterctl/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["killianmuldoon"]} -->
k8s-ci-robot: @killianmuldoon: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-cluster-api-verify-main | 03ba10acd37da52ce93f4eb38db7ba834bf5a4a6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api/8234/pull-cluster-api-verify-main/1632805542151852032) | true | `/test pull-cluster-api-verify-main`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api&pr=8234). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Akillianmuldoon). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
sbueringer: Overall lgtm from my side. No idea what we want to do with this: https://github.com/kubernetes-sigs/cluster-api/pull/8234#discussion_r1127156569




killianmuldoon: Update the comment on `WatchNamespace` to refer directly to the contract. We could, alternatively, remove the explanation if we're not confident that's the meaning of the original comment.
k8s-ci-robot: @killianmuldoon: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-cluster-api-verify-main | 4d9ac647b766b9592fcc1e4affa6a7a8b034aea5 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api/8234/pull-cluster-api-verify-main/1633435868855275520) | true | `/test pull-cluster-api-verify-main`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api&pr=8234). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Akillianmuldoon). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
sbueringer: Fine for me!
lgtm pending regen

Patch:
diff --git a/Makefile b/Makefile
index 2c4cababe..f344205b9 100644
--- a/Makefile
+++ b/Makefile
@@ -133,7 +133,7 @@ ENVSUBST_VER := $(call get_go_version,github.com/drone/envsubst/v2)
 ENVSUBST := $(abspath $(TOOLS_BIN_DIR)/$(ENVSUBST_BIN)-$(ENVSUBST_VER))
 ENVSUBST_PKG := github.com/drone/envsubst/v2/cmd/envsubst
 
-GO_APIDIFF_VER := v0.6.0
+GO_APIDIFF_VER := v0.5.0
 GO_APIDIFF_BIN := go-apidiff
 GO_APIDIFF := $(abspath $(TOOLS_BIN_DIR)/$(GO_APIDIFF_BIN)-$(GO_APIDIFF_VER))
 GO_APIDIFF_PKG := github.com/joelanford/go-apidiff
diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go
index 5fa401dcb..9c201109e 100644
--- a/api/v1beta1/common_types.go
+++ b/api/v1beta1/common_types.go
@@ -146,16 +146,6 @@ const (
 	VariableDefinitionFromInline = "inline"
 )
 
-// NodeUninitializedTaint can be added to Nodes at creation by the bootstrap provider, e.g. the
-// KubeadmBootstrap provider will add the taint.
-// This taint is used to prevent workloads to be scheduled on Nodes before the node is initialized by Cluster API.
-// As of today the Node initialization consists of syncing labels from Machines to Nodes. Once the labels
-// have been initially synced the taint is removed from the Node.
-var NodeUninitializedTaint = corev1.Taint{
-	Key:    "node.cluster.x-k8s.io/uninitialized",
-	Effect: corev1.TaintEffectNoSchedule,
-}
-
 const (
 	// TemplateSuffix is the object kind suffix used by template types.
 	TemplateSuffix = "Template"
diff --git a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
index ee8f63994..e12305a9c 100644
--- a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
+++ b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
@@ -63,24 +63,6 @@ const (
 	KubeadmConfigControllerName = "kubeadmconfig-controller"
 )
 
-var (
-	// controlPlaneTaint is the taint that kubeadm applies to the control plane nodes
-	// for Kubernetes version >= v1.24.0.
-	// The values are copied from kubeadm codebase.
-	controlPlaneTaint = corev1.Taint{
-		Key:    "node-role.kubernetes.io/control-plane",
-		Effect: corev1.TaintEffectNoSchedule,
-	}
-
-	// oldControlPlaneTaint is the taint that kubeadm applies to the control plane nodes
-	// for Kubernetes version < v1.25.0.
-	// The values are copied from kubeadm codebase.
-	oldControlPlaneTaint = corev1.Taint{
-		Key:    "node-role.kubernetes.io/master",
-		Effect: corev1.TaintEffectNoSchedule,
-	}
-)
-
 const (
 	// DefaultTokenTTL is the default TTL used for tokens.
 	DefaultTokenTTL = 15 * time.Minute
@@ -433,15 +415,7 @@ func (r *KubeadmConfigReconciler) handleClusterNotInitialized(ctx context.Contex
 			},
 		}
 	}
-
-	// Add the node uninitialized taint to the list of taints.
-	// DeepCopy the InitConfiguration to prevent updating the actual KubeadmConfig.
-	// Do not modify the KubeadmConfig in etcd as this is a temporary taint that will be dropped after the node
-	// is initialized by ClusterAPI.
-	initConfiguration := scope.Config.Spec.InitConfiguration.DeepCopy()
-	addNodeUninitializedTaint(&initConfiguration.NodeRegistration, true, parsedVersion)
-
-	initdata, err := kubeadmtypes.MarshalInitConfigurationForVersion(initConfiguration, parsedVersion)
+	initdata, err := kubeadmtypes.MarshalInitConfigurationForVersion(scope.Config.Spec.InitConfiguration, parsedVersion)
 	if err != nil {
 		scope.Error(err, "Failed to marshal init configuration")
 		return ctrl.Result{}, err
@@ -577,14 +551,7 @@ func (r *KubeadmConfigReconciler) joinWorker(ctx context.Context, scope *Scope)
 		return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
 	}
 
-	// Add the node uninitialized taint to the list of taints.
-	// DeepCopy the JoinConfiguration to prevent updating the actual KubeadmConfig.
-	// Do not modify the KubeadmConfig in etcd as this is a temporary taint that will be dropped after the node
-	// is initialized by ClusterAPI.
-	joinConfiguration := scope.Config.Spec.JoinConfiguration.DeepCopy()
-	addNodeUninitializedTaint(&joinConfiguration.NodeRegistration, false, parsedVersion)
-
-	joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(joinConfiguration, parsedVersion)
+	joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, parsedVersion)
 	if err != nil {
 		scope.Error(err, "Failed to marshal join configuration")
 		return ctrl.Result{}, err
@@ -690,14 +657,7 @@ func (r *KubeadmConfigReconciler) joinControlplane(ctx context.Context, scope *S
 		return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
 	}
 
-	// Add the node uninitialized taint to the list of taints.
-	// DeepCopy the JoinConfiguration to prevent updating the actual KubeadmConfig.
-	// Do not modify the KubeadmConfig in etcd as this is a temporary taint that will be dropped after the node
-	// is initialized by ClusterAPI.
-	joinConfiguration := scope.Config.Spec.JoinConfiguration.DeepCopy()
-	addNodeUninitializedTaint(&joinConfiguration.NodeRegistration, true, parsedVersion)
-
-	joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(joinConfiguration, parsedVersion)
+	joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, parsedVersion)
 	if err != nil {
 		scope.Error(err, "Failed to marshal join configuration")
 		return ctrl.Result{}, err
@@ -1106,43 +1066,3 @@ func (r *KubeadmConfigReconciler) ensureBootstrapSecretOwnersRef(ctx context.Con
 	}
 	return nil
 }
-
-// addNodeUninitializedTaint adds the NodeUninitializedTaint to the nodeRegistration.
-// Note: If isControlPlane is true then it also adds the control plane taint if the initial set of taints is nil.
-// This is to ensure consistency with kubeadm's defaulting behavior.
-func addNodeUninitializedTaint(nodeRegistration *bootstrapv1.NodeRegistrationOptions, isControlPlane bool, kubernetesVersion semver.Version) {
-	var taints []corev1.Taint
-	taints = nodeRegistration.Taints
-	if hasTaint(taints, clusterv1.NodeUninitializedTaint) {
-		return
-	}
-
-	// For a control plane, kubeadm adds the default control plane taint if the provided taints are nil.
-	// Since we are adding the uninitialized taint we also have to add the default taints kubeadm would have added if
-	// the taints were nil.
-	if isControlPlane && taints == nil {
-		// Note: Kubeadm uses a different default control plane taint depending on the kubernetes version.
-		// Ref: https://github.com/kubernetes/kubeadm/issues/2200
-		if kubernetesVersion.LT(semver.MustParse("1.24.0")) {
-			taints = []corev1.Taint{oldControlPlaneTaint}
-		} else if kubernetesVersion.GTE(semver.MustParse("1.24.0")) && kubernetesVersion.LT(semver.MustParse("1.25.0")) {
-			taints = []corev1.Taint{
-				oldControlPlaneTaint,
-				controlPlaneTaint,
-			}
-		} else {
-			taints = []corev1.Taint{controlPlaneTaint}
-		}
-	}
-	taints = append(taints, clusterv1.NodeUninitializedTaint)
-	nodeRegistration.Taints = taints
-}
-
-func hasTaint(taints []corev1.Taint, targetTaint corev1.Taint) bool {
-	for _, taint := range taints {
-		if taint.MatchTaint(&targetTaint) {
-			return true
-		}
-	}
-	return false
-}
diff --git a/cmd/clusterctl/api/v1alpha3/provider_type.go b/cmd/clusterctl/api/v1alpha3/provider_type.go
index ce5b2bce8..ba67861bf 100644
--- a/cmd/clusterctl/api/v1alpha3/provider_type.go
+++ b/cmd/clusterctl/api/v1alpha3/provider_type.go
@@ -50,7 +50,7 @@ type Provider struct {
 	// WatchedNamespace indicates the namespace where the provider controller is watching.
 	// If empty the provider controller is watching for objects in all namespaces.
 	//
-	// Deprecated: in clusterctl v1alpha4 all the providers watch all the namespaces; this field will be removed in a future version of this API
+	// Deprecated: providers complying with the Cluster API v1alpha4 contract or above must watch all namespaces; this field will be removed in a future version of this API
 	// +optional
 	WatchedNamespace string `json:"watchedNamespace,omitempty"`
 }
diff --git a/cmd/clusterctl/client/alpha/machinedeployment.go b/cmd/clusterctl/client/alpha/machinedeployment.go
index d4466c511..f5e66d21c 100644
--- a/cmd/clusterctl/client/alpha/machinedeployment.go
+++ b/cmd/clusterctl/client/alpha/machinedeployment.go
@@ -118,7 +118,7 @@ func findMachineDeploymentRevision(toRevision int64, allMSs []*clusterv1.Machine
 }
 
 // getMachineSetsForDeployment returns a list of MachineSets associated with a MachineDeployment.
-func getMachineSetsForDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeployment) ([]*clusterv1.MachineSet, error) {
+func getMachineSetsForDeployment(proxy cluster.Proxy, d *clusterv1.MachineDeployment) ([]*clusterv1.MachineSet, error) {
 	log := logf.Log
 	c, err := proxy.NewClient()
 	if err != nil {
@@ -126,7 +126,7 @@ func getMachineSetsForDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeplo
 	}
 	// List all MachineSets to find those we own but that no longer match our selector.
 	machineSets := &clusterv1.MachineSetList{}
-	if err := c.List(ctx, machineSets, client.InNamespace(md.Namespace)); err != nil {
+	if err := c.List(ctx, machineSets, client.InNamespace(d.Namespace)); err != nil {
 		return nil, err
 	}
 
@@ -135,12 +135,12 @@ func getMachineSetsForDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeplo
 		ms := &machineSets.Items[idx]
 
 		// Skip this MachineSet if its controller ref is not pointing to this MachineDeployment
-		if !metav1.IsControlledBy(ms, md) {
+		if !metav1.IsControlledBy(ms, d) {
 			log.V(5).Info("Skipping MachineSet, controller ref does not match MachineDeployment", "machineset", ms.Name)
 			continue
 		}
 
-		selector, err := metav1.LabelSelectorAsSelector(&md.Spec.Selector)
+		selector, err := metav1.LabelSelectorAsSelector(&d.Spec.Selector)
 		if err != nil {
 			log.V(5).Info("Skipping MachineSet, failed to get label selector from spec selector", "machineset", ms.Name)
 			continue
diff --git a/cmd/clusterctl/client/alpha/rollout_rollbacker.go b/cmd/clusterctl/client/alpha/rollout_rollbacker.go
index d9832e7db..d2c7e69df 100644
--- a/cmd/clusterctl/client/alpha/rollout_rollbacker.go
+++ b/cmd/clusterctl/client/alpha/rollout_rollbacker.go
@@ -47,7 +47,7 @@ func (r *rollout) ObjectRollbacker(proxy cluster.Proxy, ref corev1.ObjectReferen
 }
 
 // rollbackMachineDeployment will rollback to a previous MachineSet revision used by this MachineDeployment.
-func rollbackMachineDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeployment, toRevision int64) error {
+func rollbackMachineDeployment(proxy cluster.Proxy, d *clusterv1.MachineDeployment, toRevision int64) error {
 	log := logf.Log
 	c, err := proxy.NewClient()
 	if err != nil {
@@ -57,7 +57,7 @@ func rollbackMachineDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeploym
 	if toRevision < 0 {
 		return errors.Errorf("revision number cannot be negative: %v", toRevision)
 	}
-	msList, err := getMachineSetsForDeployment(proxy, md)
+	msList, err := getMachineSetsForDeployment(proxy, d)
 	if err != nil {
 		return err
 	}
@@ -67,7 +67,7 @@ func rollbackMachineDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeploym
 		return err
 	}
 	log.V(7).Info("Found revision", "revision", msForRevision)
-	patchHelper, err := patch.NewHelper(md, c)
+	patchHelper, err := patch.NewHelper(d, c)
 	if err != nil {
 		return err
 	}
@@ -75,6 +75,6 @@ func rollbackMachineDeployment(proxy cluster.Proxy, md *clusterv1.MachineDeploym
 	revMSTemplate := *msForRevision.Spec.Template.DeepCopy()
 	delete(revMSTemplate.Labels, clusterv1.MachineDeploymentUniqueLabel)
 
-	md.Spec.Template = revMSTemplate
-	return patchHelper.Patch(ctx, md)
+	d.Spec.Template = revMSTemplate
+	return patchHelper.Patch(ctx, d)
 }
diff --git a/cmd/clusterctl/client/client.go b/cmd/clusterctl/client/client.go
index 05d229503..1f7d4b093 100644
--- a/cmd/clusterctl/client/client.go
+++ b/cmd/clusterctl/client/client.go
@@ -54,9 +54,7 @@ type Client interface {
 	// Move moves all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target management cluster.
 	Move(options MoveOptions) error
 
-	// PlanUpgrade returns a set of suggested Upgrade plans for the cluster, and more specifically:
-	// - Upgrade to the latest version in the v1alpha3 series: ....
-	// - Upgrade to the latest version in the v1alpha4 series: ....
+	// PlanUpgrade returns a set of suggested Upgrade plans for the cluster.
 	PlanUpgrade(options PlanUpgradeOptions) ([]UpgradePlan, error)
 
 	// PlanCertManagerUpgrade returns a CertManagerUpgradePlan.
diff --git a/cmd/clusterctl/client/cluster/upgrader.go b/cmd/clusterctl/client/cluster/upgrader.go
index 43400ec59..1ca5ea4f1 100644
--- a/cmd/clusterctl/client/cluster/upgrader.go
+++ b/cmd/clusterctl/client/cluster/upgrader.go
@@ -38,9 +38,7 @@ import (
 
 // ProviderUpgrader defines methods for supporting provider upgrade.
 type ProviderUpgrader interface {
-	// Plan returns a set of suggested Upgrade plans for the management cluster, and more specifically:
-	//   - Upgrade to the latest version in the v1alpha3 series: ....
-	//   - Upgrade to the latest version in the v1alpha4 series: ....
+	// Plan returns a set of suggested Upgrade plans for the management cluster.
 	Plan() ([]UpgradePlan, error)
 
 	// ApplyPlan executes an upgrade following an UpgradePlan generated by clusterctl.
@@ -109,7 +107,7 @@ func (u *providerUpgrader) Plan() ([]UpgradePlan, error) {
 	// all the providers can upgrade to the latest release supporting v1alpha5 (not supported in current clusterctl release,
 	// but upgrade plan should report these options)
 	// Please note that upgrade plan also works on management cluster still in v1alpha3. In this case upgrade plan is shown, but
-	// upgrade to latest version in the v1alpha3 series are not supported using clusterctl v1alpha4 (use older releases).
+	// upgrade to latest version in the v1alpha3 series are not supported using clusterctl v1alpha4 or v1beta1 (use older releases).
 
 	// Gets the upgrade info for the core provider.
 	coreProviders := providerList.FilterCore()
diff --git a/cmd/clusterctl/client/init.go b/cmd/clusterctl/client/init.go
index aefeb8e70..3c4540a64 100644
--- a/cmd/clusterctl/client/init.go
+++ b/cmd/clusterctl/client/init.go
@@ -100,7 +100,7 @@ func (c *clusterctlClient) Init(options InitOptions) ([]Components, error) {
 		return nil, err
 	}
 
-	// Ensure this command only runs against v1alpha4 management clusters
+	// Ensure this command only runs against v1beta1 management clusters
 	if err := clusterClient.ProviderInventory().CheckCAPIContract(cluster.AllowCAPINotInstalled{}); err != nil {
 		return nil, err
 	}
@@ -172,7 +172,7 @@ func (c *clusterctlClient) InitImages(options InitOptions) ([]string, error) {
 		return nil, err
 	}
 
-	// Ensure this command only runs against empty management clusters or v1alpha4 management clusters.
+	// Ensure this command only runs against empty management clusters or v1beta1 management clusters.
 	if err := clusterClient.ProviderInventory().CheckCAPIContract(cluster.AllowCAPINotInstalled{}); err != nil {
 		return nil, err
 	}
diff --git a/cmd/clusterctl/config/crd/bases/clusterctl.cluster.x-k8s.io_providers.yaml b/cmd/clusterctl/config/crd/bases/clusterctl.cluster.x-k8s.io_providers.yaml
index 6a9f581b7..d3e824930 100644
--- a/cmd/clusterctl/config/crd/bases/clusterctl.cluster.x-k8s.io_providers.yaml
+++ b/cmd/clusterctl/config/crd/bases/clusterctl.cluster.x-k8s.io_providers.yaml
@@ -61,9 +61,9 @@ spec:
           watchedNamespace:
             description: "WatchedNamespace indicates the namespace where the provider
               controller is watching. If empty the provider controller is watching
-              for objects in all namespaces. \n Deprecated: in clusterctl v1alpha4
-              all the providers watch all the namespaces; this field will be removed
-              in a future version of this API"
+              for objects in all namespaces. \n Deprecated: providers complying with
+              the Cluster API v1alpha4 contract or above must watch all namespaces;
+              this field will be removed in a future version of this API"
             type: string
         type: object
     served: true
diff --git a/cmd/clusterctl/config/manifest/clusterctl-api.yaml b/cmd/clusterctl/config/manifest/clusterctl-api.yaml
index d2564461c..2c70b6545 100644
--- a/cmd/clusterctl/config/manifest/clusterctl-api.yaml
+++ b/cmd/clusterctl/config/manifest/clusterctl-api.yaml
@@ -60,9 +60,9 @@ spec:
           watchedNamespace:
             description: "WatchedNamespace indicates the namespace where the provider
               controller is watching. If empty the provider controller is watching
-              for objects in all namespaces. \n Deprecated: in clusterctl v1alpha4
-              all the providers watch all the namespaces; this field will be removed
-              in a future version of this API"
+              for objects in all namespaces. \n Deprecated: providers complying with
+              the Cluster API v1alpha4 contract or above must watch all namespaces;
+              this field will be removed in a future version of this API"
             type: string
         type: object
     served: true
diff --git a/docs/book/src/clusterctl/developers.md b/docs/book/src/clusterctl/developers.md
index 1170b016b..e5f392579 100644
--- a/docs/book/src/clusterctl/developers.md
+++ b/docs/book/src/clusterctl/developers.md
@@ -33,7 +33,7 @@ If you want to create a local artifact, follow these instructions:
 
 ### Build artifacts locally
 
-In order to build artifacts for the CAPI core provider, the kubeadm bootstrap provider, the kubeadm control plane provider and the Docker infrastructure provider:
+In order to build artifacts for the CAPI core provider, the kubeadm bootstrap provider, the kubeadm control plane provider and the docker infrastructure provider:
 
 ```bash
 make docker-build REGISTRY=gcr.io/k8s-staging-cluster-api PULL_POLICY=IfNotPresent
@@ -96,7 +96,7 @@ during your dev session.
 The above config file changes the location of the [overrides layer] folder thus ensuring
 you dev session isn't hijacked by other local artifacts.
 
-With the only exception of the Docker provider, the local repository folder does not contain cluster templates,
+With the only exception of the docker provider, the local repository folder does not contain cluster templates,
 so the `clusterctl generate cluster` command will fail.
 
 </aside>
@@ -126,11 +126,11 @@ please note that each `provider_repo` should have its own `clusterctl-settings.j
 ## Create a kind management cluster
 
 [kind] can provide a Kubernetes cluster to be used as a management cluster.
-See [Install and/or configure a Kubernetes cluster] for more information.
+See [Install and/or configure a kubernetes cluster] for more information.
 
 *Before* running clusterctl init, you must ensure all the required images are available in the kind cluster.
 
-This is always the case for images published in some image repository like Docker Hub or gcr.io, but it can't be
+This is always the case for images published in some image repository like docker hub or gcr.io, but it can't be
 the case for images built locally; in this case, you can use `kind load` to move the images built locally. e.g.
 
 ```bash
@@ -148,7 +148,7 @@ script.
 
 Optionally, you may want to check if the components are running properly. The
 exact components are dependent on which providers you have initialized. Below
-is an example output with the Docker provider being installed.
+is an example output with the docker provider being installed.
 
 ```bash
 kubectl get deploy -A | grep  "cap\|cert"
@@ -166,7 +166,7 @@ cert-manager                        cert-manager-webhook
 
 ## Additional Notes for the Docker Provider
 
-### Select the appropriate Kubernetes version
+### Select the appropriate kubernetes version
 
 When selecting the `--kubernetes-version`, ensure that the `kindest/node`
 image is available.
@@ -205,6 +205,6 @@ sed -i -e "s/server:.*/server: https:\/\/$(docker port capi-quickstart-lb 6443/t
 [kind]: https://kind.sigs.k8s.io/
 [providers repositories]: configuration.md#provider-repositories
 [overrides layer]: configuration.md#overrides-layer
-[Install and/or configure a Kubernetes cluster]: ../user/quick-start.md#install-andor-configure-a-kubernetes-cluster
+[Install and/or configure a kubernetes cluster]: ../user/quick-start.md#install-andor-configure-a-kubernetes-cluster
 [kind-docker-hub]: https://hub.docker.com/r/kindest/node/tags
 [issue 3795]: https://github.com/kubernetes-sigs/cluster-api/issues/3795
diff --git a/docs/book/src/clusterctl/provider-contract.md b/docs/book/src/clusterctl/provider-contract.md
index a152d8759..6ad30e9cb 100644
--- a/docs/book/src/clusterctl/provider-contract.md
+++ b/docs/book/src/clusterctl/provider-contract.md
@@ -436,7 +436,7 @@ that are compliant with one of the following rules:
   * The object is directly or indirectly linked to a `ClusterResourceSet` object (through the `OwnerReference` chain).
   * The object is directly or indirectly linked to another object with the `clusterctl.cluster.x-k8s.io/move-hierarchy`
     label, e.g. the infrastructure Provider ClusterIdentity objects (linked through the `OwnerReference` chain).
-  * The object has the `clusterctl.cluster.x-k8s.io/move` label or the `clusterctl.cluster.x-k8s.io/move-hierarchy` label,
+  * The object hase the `clusterctl.cluster.x-k8s.io/move` label or the `clusterctl.cluster.x-k8s.io/move-hierarchy` label,
     e.g. the CPI config secret.
 
 Note. `clusterctl.cluster.x-k8s.io/move` and `clusterctl.cluster.x-k8s.io/move-hierarchy` labels could be applied
diff --git a/docs/book/src/developer/architecture/controllers/cluster-topology.md b/docs/book/src/developer/architecture/controllers/cluster-topology.md
index 0aeee2780..b1dd4bdfe 100644
--- a/docs/book/src/developer/architecture/controllers/cluster-topology.md
+++ b/docs/book/src/developer/architecture/controllers/cluster-topology.md
@@ -12,7 +12,7 @@ Its main responsibilities are to:
 
 The high level workflow of ClusterTopology reconciliation is shown below.
 
-![ClusterTopology Reconciler Component Diagram](../../../images/cluster-topology-reconciller.png)
+![ClusterTopology Reconciller Component Diagram](../../../images/cluster-topology-reconciller.png)
 
 ### Additional information
 
diff --git a/docs/book/src/developer/architecture/controllers/control-plane.md b/docs/book/src/developer/architecture/controllers/control-plane.md
index 0d9e34bb3..2eece2fa8 100644
--- a/docs/book/src/developer/architecture/controllers/control-plane.md
+++ b/docs/book/src/developer/architecture/controllers/control-plane.md
@@ -180,7 +180,7 @@ following fields defined:
       introspection by clients, and is used to provide the CRD-based integration
       for the scale subresource and additional integrations for things like
       kubectl describe. The string will be in the same format as the query-param
-      syntax. More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
+      syntax. More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors
     </td>
     <td></td>
   </tr>
diff --git a/docs/book/src/developer/architecture/controllers/machine-pool.md b/docs/book/src/developer/architecture/controllers/machine-pool.md
index 964405796..04cd327e1 100644
--- a/docs/book/src/developer/architecture/controllers/machine-pool.md
+++ b/docs/book/src/developer/architecture/controllers/machine-pool.md
@@ -10,7 +10,7 @@ The MachinePool controller's main responsibilities are:
     * The associated InfrastructureMachinePool object.
 * Copy data from `BootstrapConfig.Status.DataSecretName` to `MachinePool.Spec.Template.Spec.Bootstrap.DataSecretName` if
 `MachinePool.Spec.Template.Spec.Bootstrap.DataSecretName` is empty.
-* Setting NodeRefs on MachinePool instances to be able to associate them with Kubernetes nodes.
+* Setting NodeRefs on MachinePool instances to be able to associate them with kubernetes nodes.
 * Deleting Nodes in the target cluster when the associated MachinePool instance is deleted.
 * Keeping the MachinePool's Status object up to date with the InfrastructureMachinePool's Status object.
 * Finding Kubernetes nodes matching the expected providerIDs in the workload cluster.
diff --git a/docs/book/src/developer/architecture/controllers/machine.md b/docs/book/src/developer/architecture/controllers/machine.md
index 679a9cb6f..60a235f16 100644
--- a/docs/book/src/developer/architecture/controllers/machine.md
+++ b/docs/book/src/developer/architecture/controllers/machine.md
@@ -10,7 +10,7 @@ The Machine controller's main responsibilities are:
     * The associated InfrastructureMachine object.
 * Copy data from `BootstrapConfig.Status.DataSecretName` to `Machine.Spec.Bootstrap.DataSecretName` if
 `Machine.Spec.Bootstrap.DataSecretName` is empty.
-* Setting NodeRefs to be able to associate machines and Kubernetes nodes.
+* Setting NodeRefs to be able to associate machines and kubernetes nodes.
 * Deleting Nodes in the target cluster when the associated machine is deleted.
 * Cleanup of related objects.
 * Keeping the Machine's Status object up to date with the InfrastructureMachine's Status object.
diff --git a/docs/book/src/developer/logging.md b/docs/book/src/developer/logging.md
index fc642c565..c5afde93b 100644
--- a/docs/book/src/developer/logging.md
+++ b/docs/book/src/developer/logging.md
@@ -137,7 +137,7 @@ We are working to continuously improving this experience, allowing Cluster API d
 For the best experience exploring the logs using Tilt:
 1. Set `--logging-format=json`. 
 2. Set a high log verbosity, e.g. `v=5`.
-3. Enable Promtail, Loki, and Grafana under `deploy_observability`.
+3. Enable promtail, loki, and grafana under deploy_observability.
 
 A minimal example of a tilt-settings.yaml file that deploys a ready-to-use logging suite looks like:
 ```yaml
diff --git a/docs/book/src/developer/providers/bootstrap.md b/docs/book/src/developer/providers/bootstrap.md
index 1ff1fef50..c25eed0e7 100644
--- a/docs/book/src/developer/providers/bootstrap.md
+++ b/docs/book/src/developer/providers/bootstrap.md
@@ -123,13 +123,6 @@ The following diagram shows the typical logic for a bootstrap provider:
 
 A bootstrap provider's bootstrap data must create `/run/cluster-api/bootstrap-success.complete` (or `C:\run\cluster-api\bootstrap-success.complete` for Windows machines) upon successful bootstrapping of a Kubernetes node. This allows infrastructure providers to detect and act on bootstrap failures.
 
-## Taint Nodes at creation
-
-A bootstrap provider can optionally taint nodes at creation with `node.cluster.x-k8s.io/uninitialized:NoSchedule`.
-This taint is used to prevent workloads to be scheduled on Nodes before the node is initialized by Cluster API.
-As of today the Node initialization consists of syncing labels from Machines to Nodes. Once the labels have been 
-initially synced the taint is removed form the Node.
-
 ## RBAC
 
 ### Provider controller
diff --git a/docs/book/src/developer/providers/contracts.md b/docs/book/src/developer/providers/contracts.md
index 6aee48288..906e49508 100644
--- a/docs/book/src/developer/providers/contracts.md
+++ b/docs/book/src/developer/providers/contracts.md
@@ -5,7 +5,7 @@ Cluster API defines a contract which requires providers to implement certain fie
 Cluster API defines the following contracts:
 
 - [Infrastructure provider contract](./cluster-infrastructure.md)
-- [Bootstrap provider contract](./bootstrap.md)
+- [Boostrap provider contract](./bootstrap.md)
 - [Control Plane provider contract](../../developer/architecture/controllers/control-plane.md#crd-contracts)
 - [Machine provider contract](./machine-infrastructure.md)
 - [clusterctl provider contract](../../clusterctl/provider-contract.md#clusterctl-provider-contract)
@@ -14,7 +14,7 @@ Cluster API defines the following contracts:
 ## API version labels
 Providers MUST set `cluster.x-k8s.io/<version>` label on all Custom Resource Definitions related to Cluster API starting with v1alpha3.
 The label is a map from an API Version of Cluster API (contract) to your Custom Resource Definition versions.
-The value is an underscore-delimited (_) list of versions.
+The value is a underscore-delimited (_) list of versions.
 Each value MUST point to an available version in your CRD Spec.
 
 The label allows Cluster API controllers to perform automatic conversions for object references, the controllers will pick the last available version in the list if multiple versions are found.
@@ -33,4 +33,4 @@ An example of this is in the [Kubeadm Bootstrap provider](https://github.com/kub
 
 ## Improving and contributing to the contract
 
-The definition of the contract between Cluster API and providers may be changed in future versions of Cluster API. The Cluster API maintainers welcome feedback and contributions to the contract in order to improve how it's defined, its clarity and visibility to provider implementers and its suitability across the different kinds of Cluster API providers. To provide feedback or open a discussion about the provider contract please [open an issue on the Cluster API](https://github.com/kubernetes-sigs/cluster-api/issues/new?assignees=&labels=&template=feature_request.md) repo or add an item to the agenda in the [Cluster API community meeting](https://git.k8s.io/community/sig-cluster-lifecycle/README.md#cluster-api).
+The definition of the contract between Cluster API and providers may be changed in future versions of Cluster API. The Cluster API maintainers welcome feedback and contributions to the contract in order to improve how it's defined, its clarity and visibility to provider implementers and its suitability across the different kinds of Cluster API providers. To provide feedback or open a discussion about the provider contract please [open an issue on the Cluster API](https://github.com/kubernetes-sigs/cluster-api/issues/new?assignees=&labels=&template=feature_request.md) repo or add an item to the agenda in the [Cluster API community meeting](http://git.k8s.io/community/sig-cluster-lifecycle/README.md#cluster-api).
diff --git a/docs/book/src/developer/providers/v0.3-to-v0.4.md b/docs/book/src/developer/providers/v0.3-to-v0.4.md
index 5af8084d6..41481ff8d 100644
--- a/docs/book/src/developer/providers/v0.3-to-v0.4.md
+++ b/docs/book/src/developer/providers/v0.3-to-v0.4.md
@@ -22,7 +22,7 @@
 
 - The `test` folder now ships with its own Go module `sigs.k8s.io/cluster-api/test`.
 - The module is going to be tagged and versioned as part of the release.
-- Folks importing the test e2e framework or the Docker infrastructure provider need to import the new module.
+- Folks importing the test e2e framework or the docker infrastructure provider need to import the new module.
   - When imported, the test module version should always match the Cluster API one.
   - Add the following line in `go.mod` to replace the cluster-api dependency in the test module (change the version to your current Cluster API version):
   ```
@@ -199,7 +199,7 @@ should be executed before this changes.
 
 **Changes in the `/config/default` folder:**
 
-1. Edit the `/config/default/kustomization.yaml` file and replace all the occurrences of
+1. Edit the `/config/default/kustomization.yaml` file and replace all the occurencies of
    ```
          kind: Certificate
          group: cert-manager.io
diff --git a/docs/book/src/developer/providers/v1.0-to-v1.1.md b/docs/book/src/developer/providers/v1.0-to-v1.1.md
index a0291b85f..f7b2759df 100644
--- a/docs/book/src/developer/providers/v1.0-to-v1.1.md
+++ b/docs/book/src/developer/providers/v1.0-to-v1.1.md
@@ -65,5 +65,5 @@ are kept in sync with the versions used by `sigs.k8s.io/controller-runtime`.
   fully exploit this feature, it is required to pass the `LogFolder` parameter when calling `CreateKindBootstrapClusterAndLoadImages`. Please see this [PR](https://github.com/kubernetes-sigs/cluster-api/pull/5910) for an example on how to use it. 
 * The `gci` linter has been enabled to enforce consistent imports. As usual, feel free to take a look at our linter config, but of course it's not mandatory to adopt it.
 * The Tilt dev setup has been extended with:
-    * [an option to deploy Grafana, Loki and Promtail](https://github.com/kubernetes-sigs/cluster-api/pull/5336) 
+    * [an option to deploy Grafana, Loki and promtail](https://github.com/kubernetes-sigs/cluster-api/pull/5336) 
     * [options to ease debugging of controllers (delve, profiler, metrics)](https://github.com/kubernetes-sigs/cluster-api/pull/5485) 
diff --git a/docs/book/src/developer/providers/v1.2-to-v1.3.md b/docs/book/src/developer/providers/v1.2-to-v1.3.md
index 94d34055b..51f77bbce 100644
--- a/docs/book/src/developer/providers/v1.2-to-v1.3.md
+++ b/docs/book/src/developer/providers/v1.2-to-v1.3.md
@@ -62,14 +62,14 @@ The default value is 0, meaning that the volume can be detached without any time
 - The `Move` function in E2E test framework for clusterctl has been modified to:
   * print the `clusterctl move` command including the arguments similar to `Init`.
   * log the output to the a `clusterctl-move.log` file at the subdirectory `logs/<namespace>`.
-- The self-hosted upgrade test now also upgrades the self-hosted cluster's Kubernetes version by default. For that it requires the following variables to be set:
+- The self-hosted upgrade test now also upgrades the self-hosted clusters kubernetes version by default. For that it requires the following variables to be set:
   * `KUBERNETES_VERSION_UPGRADE_FROM`
   * `KUBERNETES_VERSION_UPGRADE_TO`
   * `ETCD_VERSION_UPGRADE_TO`
   * `COREDNS_VERSION_UPGRADE_TO`
-  The variable `SkipUpgrade` could be set to revert to the old behaviour by making use of the `KUBERNETES_VERSION` variable and skipping the Kubernetes upgrade.
+  The variable `SkipUpgrade` could be set to revert to the old behaviour by making use of the `KUBERNETES_VERSION` variable and skipping the kubernetes upgrade.
 - cert-manager upgraded from v1.9.1 to v1.10.1.
-- Machine `providerID` is now being strictly checked for equality when compared against Kubernetes node `providerID` data. This is the expected criteria for correlating a Cluster API machine to its corresponding Kubernetes node, but historically this comparison was not strict, and instead compared only against the `ID` substring part of the full `providerID` string. Because different providers construct `providerID` strings differently, the `ID` substring is not uniformly defined and implemented across providers, and thus the existing `providerID` equality cannot guarantee the correct Machine-Node correlation. It is very unlikely that this new behavior will break existing providers, but FYI: if strict `providerID` equality will degrade expected behaviors, you may need to update your provider implementation prior to adopting Cluster API v1.3.
+- Machine `providerID` is now being strictly checked for equality when compared against Kubernetes node `providerID` data. This is the expected criteria for correlating a Cluster API machine to its corresponding Kubernetes node, but historically this comparison was not strict, and instead compared only against the `ID` substring part of the full `providerID` string. Because different providers construct `providerID` strings differently, the `ID` substring is not uniformly defined and implemented across providers, and thus the existing `providerID` equality can not guarantee the correct Machine-Node correlation. It is very unlikely that this new behavior will break existing providers, but FYI: if strict `providerID` equality will degrade expected behaviors, you may need to update your provider implementation prior to adopting Cluster API v1.3.
 - The default minimum TLS version in use by the webhook servers is 1.2.
 - OwnerReferences are now more strictly enforced for objects managed by Cluster API. Machines, Bootstrap configs, Infrastructure Machines and Secrets created by CAPI components [now have strictly enforced controller owner references](https://github.com/kubernetes-sigs/cluster-api/issues/7575). This is not expected to require changes for providers.
 
diff --git a/docs/book/src/developer/providers/v1.3-to-v1.4.md b/docs/book/src/developer/providers/v1.3-to-v1.4.md
index 574c78f20..5873897d4 100644
--- a/docs/book/src/developer/providers/v1.3-to-v1.4.md
+++ b/docs/book/src/developer/providers/v1.3-to-v1.4.md
@@ -13,7 +13,6 @@ maintainers of providers and consumers of our Go API.
 
 - sigs.k8s.io/controller-runtime: v0.13.x => v0.14.x
 - sigs.k8s.io/controller-tools: v0.10.x => v0.11.x
-- github.com/joelanford/go-apidiff: 0.5.0 => 0.6.0
 
 ## Changes by Kind
 
diff --git a/docs/book/src/developer/repository-layout.md b/docs/book/src/developer/repository-layout.md
index 7eb2ddf35..bc6936fd3 100644
--- a/docs/book/src/developer/repository-layout.md
+++ b/docs/book/src/developer/repository-layout.md
@@ -29,7 +29,7 @@ cluster-api
 └───Makefile
 ```
 
-### GitHub
+### Github
 
 [~/.github](https://github.com/kubernetes-sigs/cluster-api/tree/main/.github)
 
@@ -57,7 +57,7 @@ This folder contains a reference implementation of a Cluster API Control Plane p
 
 ### Cluster API Provider Docker 
 
-[~/test/infrastructure/docker](https://github.com/kubernetes-sigs/cluster-api/tree/main/test/infrastructure/docker)
+[~/test/insfrastructure/docker](https://github.com/kubernetes-sigs/cluster-api/tree/main/test/infrastructure/docker)
 
 This folder contains a reference implementation of an infrastructure provider for the Cluster API project using Docker. This provider is intended for development purposes only. 
 
@@ -148,7 +148,7 @@ The [api](#api) folder contains webhooks consisting of validators and defaults f
 
 [~/internal/webhooks](https://github.com/kubernetes-sigs/cluster-api/tree/main/internal/webhooks)
 
-This directory contains the implementation of some of the Cluster API webhooks. The internal implementation means that the methods supplied by this package cannot be imported by external code bases. 
+This directory contains the implementation of some of the Cluster API webhooks. The internal implementation means that the methods supplied by this package can not be imported by external code bases. 
 
 [~/webhooks](https://github.com/kubernetes-sigs/cluster-api/tree/main/webhooks)
 
diff --git a/docs/book/src/developer/tilt.md b/docs/book/src/developer/tilt.md
index b8971ed75..42f7200a0 100644
--- a/docs/book/src/developer/tilt.md
+++ b/docs/book/src/developer/tilt.md
@@ -20,7 +20,7 @@ workflow that offers easy deployments and rapid iterative builds.
 ## Getting started
 
 ### Create a kind cluster
-A script to create a KIND cluster along with a local Docker registry and the correct mounts to run CAPD is included in the hack/ folder.
+A script to create a KIND cluster along with a local docker registry and the correct mounts to run CAPD is included in the hack/ folder.
 
 To create a pre-configured cluster run:
 
@@ -200,7 +200,7 @@ Important! This feature requires the `helm` command to be available in the user'
 Supported values are:
 
   * `grafana`*: To create dashboards and query `loki` as well as `prometheus`.
-  * `kube-state-metrics`: For exposing metrics for Kubernetes and CAPI resources to `prometheus`.
+  * `kube-state-metrics`: For exposing metrics for kubernetes and CAPI resources to `prometheus`.
   * `loki`: To receive and store logs.
   * `prometheus`*: For collecting metrics from Kubernetes.
   * `promtail`: For providing pod logs to `loki`.
@@ -265,7 +265,7 @@ Supported settings:
     }
     ```
 
-    ###### Goland / IntelliJ
+    ###### Goland / Intellij
     With the above example, you can configure [a Go Remote run/debug
     configuration](https://www.jetbrains.com/help/go/attach-to-running-go-processes-with-debugger.html#step-3-create-the-remote-run-debug-configuration-on-the-client-computer)
     pointing at port 30000.
@@ -462,7 +462,7 @@ possible (the container images do not need the entire go toolchain, source code,
 
 ## IDE support for Tiltfile
 
-For IntelliJ, Syntax highlighting for the Tiltfile can be configured with a TextMate Bundle. For instructions, please see:
+For Intellij, Syntax highlighting for the Tiltfile can be configured with a TextMate Bundle. For instructions, please see:
 [Tiltfile TextMate Bundle](https://github.com/tilt-dev/tiltfile.tmbundle).
 
 For VSCode the [Bazel plugin](https://marketplace.visualstudio.com/items?itemName=BazelBuild.vscode-bazel) can be used, it provides
@@ -475,10 +475,10 @@ syntax highlighting and auto-formatting. To enable it for Tiltfile a file associ
 
 ## Using Podman
 
-[Podman](https://podman.io) can be used instead of Docker by following these actions:
+[Podman](https://podman.io) can be used instead of docker by following these actions:
 
 1. Enable the podman unix socket (eg. `systemctl --user enable --now podman.socket` on Fedora)
-1. Set `build_engine` to `podman` in `tilt-settings.yaml` (optional, only if both Docker & podman are installed)
+1. Set `build_engine` to `podman` in `tilt-settings.yaml` (optional, only if both docker & podman are installed)
 1. Define the env variable `DOCKER_HOST` to the right socket while running tilt (eg. `DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock tilt up`)
 
 NB: The socket defined by `DOCKER_HOST` is used only for the `hack/tools/tilt-prepare` command, the image build is running the `podman build`/`podman push` commands.
diff --git a/docs/book/src/reference/glossary.md b/docs/book/src/reference/glossary.md
index 0b77cdb02..ddce00543 100644
--- a/docs/book/src/reference/glossary.md
+++ b/docs/book/src/reference/glossary.md
@@ -28,7 +28,7 @@ A temporary cluster that is used to provision a Target Management cluster.
 Refers to a [provider](#provider) that implements a solution for the [bootstrap](#bootstrap) process.
 Bootstrap provider's interaction with Cluster API is based on what is defined in the [Cluster API contract](#contract). 
 
-See [CABPK](#cabpk). 
+See [CABPK](#CABPK). 
 
 # C
 ---
@@ -145,7 +145,7 @@ The set of Kubernetes services that form the basis of a cluster. See also [https
 Refers to a [provider](#provider) that implements a solution for the management of a Kubernetes [control plane](#control-plane).
 Control plane provider's interaction with Cluster API is based on what is defined in the [Cluster API contract](#contract).
 
-See [KCP](#kcp).
+See [KCP](#KCP).
 
 ### Core provider
 
@@ -161,7 +161,7 @@ See [CAPI](#cluster-api).
 ### Default implementation
 
 A feature implementation offered as part of the Cluster API project and maintained by the CAPI core team; For example
-[KCP](#kcp) is a default implementation for a [control plane provider](#control-plane-provider).
+[KCP](#KCP) is a default implementation for a [control plane provider](#control-plane-provider).
 
 # E
 ---
@@ -179,7 +179,7 @@ A [runtime extension](#runtime-extension) that implements a [topology mutation h
 
 ### Horizontal Scaling
 
-The ability to add more machines based on policy and well-defined metrics. For example, add a machine to a cluster when CPU load average > (X) for a period of time (Y).
+The ability to add more machines based on policy and well defined metrics. For example, add a machine to a cluster when CPU load average > (X) for a period of time (Y).
 
 ### Host
 
@@ -217,7 +217,7 @@ see [Server](#server)
 
 ### Immutability
 
-A resource that does not mutate.  In Kubernetes we often state the instance of a running pod is immutable or does not change once it is run.  In order to make a change, a new pod is run.  In the context of [Cluster API](#cluster-api) we often refer to a running instance of a [Machine](#machine) as being immutable, from a [Cluster API](#cluster-api) perspective.
+A resource that does not mutate.  In kubernetes we often state the instance of a running pod is immutable or does not change once it is run.  In order to make a change, a new pod is run.  In the context of [Cluster API](#cluster-api) we often refer to a running instance of a [Machine](#machine) as being immutable, from a [Cluster API](#cluster-api) perspective.
 
 ### IPAM provider
 
@@ -265,7 +265,7 @@ Perform create, scale, upgrade, or destroy operations on the cluster.
 
 ### Managed Topology
 
-See [Topology](#topology)
+See [Topology](#Topology)
 
 ### Management cluster
 
diff --git a/docs/book/src/security/pod-security-standards.md b/docs/book/src/security/pod-security-standards.md
index c8ab7801a..0f39a98fb 100644
--- a/docs/book/src/security/pod-security-standards.md
+++ b/docs/book/src/security/pod-security-standards.md
@@ -2,7 +2,7 @@
 
 Pod Security Admission allows applying [Pod Security Standards] during creation of pods at the cluster level.
 
-The flavor `development-topology` for the Docker provider used in [Quick Start](../user/quick-start.md) already includes a basic Pod Security Standard configuration.
+The flavor `development-topology` for the docker provider used in [Quick Start](../user/quick-start.md) already includes a basic Pod Security Standard configuration.
 It is using ClusterClass variables and patches to inject the configuration.
 
 ## Adding a basic Pod Security Standards configuration to a ClusterClass
diff --git a/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md b/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md
index 3d83f4484..fdef08630 100644
--- a/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md
+++ b/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md
@@ -629,9 +629,9 @@ constant default value which can be specified in the schema is not enough.
           # If .vnetName is set, it is used. Otherwise, we will use `{{.builtin.cluster.name}}-vnet`.  
           template: "{{ if .vnetName }}{{.vnetName}}{{else}}{{.builtin.cluster.name}}-vnet{{end}}"
 ```
-When writing templates, a subset of functions from [the Sprig library](https://masterminds.github.io/sprig/) can be used to
-write expressions, e.g., `{{ .name | upper }}`. Only functions that are guaranteed to evaluate to the same result
-for a given input are allowed (e.g. `upper` or `max` can be used, while `now` or `randAlpha` cannot be used).
+When writing templates, a subset of functions from [the sprig library](http://masterminds.github.io/sprig/) can be used to
+write expressions like e.g. `{{ .name | upper }}`. Only functions that are guaranteed to evaluate to the same result
+for a given input are allowed (e.g. `upper` or `max` can be used, while `now` or `randAlpha` can not be used).
 
 ### Optional patches
 
diff --git a/docs/book/src/tasks/experimental-features/runtime-sdk/implement-topology-mutation-hook.md b/docs/book/src/tasks/experimental-features/runtime-sdk/implement-topology-mutation-hook.md
index c4df864a7..7f75f6f83 100644
--- a/docs/book/src/tasks/experimental-features/runtime-sdk/implement-topology-mutation-hook.md
+++ b/docs/book/src/tasks/experimental-features/runtime-sdk/implement-topology-mutation-hook.md
@@ -119,7 +119,7 @@ Variable definitions can be inline in the ClusterClass or from any number of ext
 of a variable definition is recorded in the `from` field in ClusterClass `.status.variables`.
 Variables that are defined by an external DiscoverVariables hook will have the name of the patch they are associated with as the value of `from`.
 Variables that are defined in the ClusterClass `.spec.variables` will have `inline` as the value of `from`.
-Note: `inline` is a reserved name for patches. It cannot be used as the name of an external patch to avoid conflicts.
+Note: `inline` is a reserved name for patches. It can not be used as the name of an external patch to avoid conflicts.
 
 If all variables that share a name have equivalent schemas the variable definitions are not in conflict. These variables can
 be set without providing `definitionFrom` value - [see below](#setting-values-for-variables-in-the-cluster). The CAPI components will
@@ -358,7 +358,7 @@ variables:
         type: array
         items:
           type: string
-        description: "preLoadImages sets the images for the Docker machines to preload."
+        description: "preLoadImages sets the images for the docker machines to preload."
   - name: podSecurityStandard
     required: false
     schema:
diff --git a/docs/book/src/tasks/multiple-providers.md b/docs/book/src/tasks/multiple-providers.md
index 4225266ba..0be7a4553 100644
--- a/docs/book/src/tasks/multiple-providers.md
+++ b/docs/book/src/tasks/multiple-providers.md
@@ -1,6 +1,6 @@
 # Running multiple providers
 
-Cluster API supports running multiple infrastructure/bootstrap/control plane providers on the same management cluster. It's highly recommended to rely on
+Cluster API supports running multiple infrastructure/bootstrap/control plane providers on the same management cluster. It's highly recommeded to rely on
 [clusterctl init](../clusterctl/commands/init.md) command in this case. [clusterctl](../clusterctl/overview.md) will help ensure that all providers support the same
 [API Version of Cluster API](../clusterctl/provider-contract.md#metadata-yaml) (contract).
 
diff --git a/docs/book/src/user/quick-start.md b/docs/book/src/user/quick-start.md
index 4370a181d..ce4ba3775 100644
--- a/docs/book/src/user/quick-start.md
+++ b/docs/book/src/user/quick-start.md
@@ -16,7 +16,6 @@ If using a [provider] that does not support v1beta1 or v1alpha4 yet, please foll
 
 - Install and setup [kubectl] in your local environment
 - Install [kind] and [Docker]
-- Install [Helm]
 
 ### Install and/or configure a Kubernetes cluster
 
@@ -102,16 +101,16 @@ a target [management cluster] on the selected [infrastructure provider].
    the workload cluster's nodes, are actually running within pods in the management cluster. In order to communicate with
    the workload cluster's API server, we'll need to expose it. We are using Kind which is a limited environment. The
    easiest way to expose the workload cluster's API server (a pod within a node running in a VM that is itself running
-   within a pod in the management cluster, that is running inside a Docker container), is to use a LoadBalancer service.
+   within a pod in the management cluster, that is running inside a docker container), is to use a LoadBalancer service.
 
    To allow using a LoadBalancer service, we can't use the kind's default CNI (kindnet), but we'll need to install
    another CNI, like Calico. In order to do that, we'll need first to initiate the kind cluster with two modifications:
    1. Disable the default CNI
-   2. Add the Docker credentials to the cluster, to avoid the Docker Hub pull rate limit of the calico images; read more
+   2. Add the docker credentials to the cluster, to avoid the docker hub pull rate limit of the calico images; read more
       about it in the [docker documentation](https://docs.docker.com/docker-hub/download-rate-limit/), and in the
       [kind documentation](https://kind.sigs.k8s.io/docs/user/private-registries/#mount-a-config-file-to-each-node).
 
-   Create a configuration file for kind. Please notice the Docker config file path, and adjust it to your local setting:
+   Create a configuration file for kind. Please notice the docker config file path, and adjust it to your local setting:
    ```bash
    cat <<EOF > kind-config.yaml
    kind: Cluster
@@ -836,17 +835,17 @@ export AZURE_RESOURCE_GROUP="<ResourceGroupName>"
 {{#/tab }}
 {{#tab CloudStack}}
 
-A Cluster API compatible image must be available in your CloudStack installation. For instructions on how to build a compatible image
-see [image-builder (CloudStack)](https://image-builder.sigs.k8s.io/capi/providers/cloudstack.html)
+A ClusterAPI compatible image must be available in your Cloudstack installation. For instructions on how to build a compatible image
+see [image-builder (Cloudstack)](https://image-builder.sigs.k8s.io/capi/providers/cloudstack.html)
 
 Prebuilt images can be found [here](http://packages.shapeblue.com/cluster-api-provider-cloudstack/images/)
 
-To see all required CloudStack environment variables execute:
+To see all required Cloudstack environment variables execute:
 ```bash
 clusterctl generate cluster --infrastructure cloudstack --list-variables capi-quickstart
 ```
 
-Apart from the script, the following CloudStack environment variables are required.
+Apart from the script, the following Cloudstack environment variables are required.
 ```bash
 # Set this to the name of the zone in which to deploy the cluster
 export CLOUDSTACK_ZONE_NAME=<zone name>
@@ -952,7 +951,7 @@ export KUBE_VIP_VERSION="v0.5.0"
 # Name of the GCP datacenter location. Change this value to your desired location
 export GCP_REGION="<GCP_REGION>"
 export GCP_PROJECT="<GCP_PROJECT>"
-# Make sure to use same Kubernetes version here as building the GCE image
+# Make sure to use same kubernetes version here as building the GCE image
 export KUBERNETES_VERSION=1.23.3
 # This is the image you built. See https://github.com/kubernetes-sigs/image-builder
 export IMAGE_ID=projects/$GCP_PROJECT/global/images/<built image>
@@ -1358,24 +1357,6 @@ Note: To use the default clusterctl method to retrieve kubeconfig for a workload
 {{#/tab }}
 {{#/tabs }}
 
-### Install a Cloud Provider
-
-The Kubernetes in-tree cloud provider implementations are being [removed](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cloud-provider/2395-removing-in-tree-cloud-providers) in favor of external cloud providers (also referred to as "out-of-tree"). This requires deploying a new component called the cloud-controller-manager which is responsible for running all the cloud specific controllers that were previously run in the kube-controller-manager. To learn more, see [this blog post](https://kubernetes.io/blog/2019/04/17/the-future-of-cloud-providers-in-kubernetes/).
-
-{{#tabs name:"tab-install-cloud-provider" tabs:"Azure"}}
-{{#tab Azure}}
-
-Install the official cloud-provider-azure Helm chart on the workload cluster:
-
-```bash
-helm install --kubeconfig=./capi-quickstart.kubeconfig --repo https://raw.githubusercontent.com/kubernetes-sigs/cloud-provider-azure/master/helm/repo cloud-provider-azure --generate-name --set infra.clusterName=capi-quickstart --set cloudControllerManager.clusterCIDR="192.168.0.0/16"
-```
-
-For more information, see the [CAPZ book](https://capz.sigs.k8s.io/topics/addons.html).
-
-{{#/tab }}
-{{#/tabs }}
-
 ### Deploy a CNI solution
 
 Calico is used here as an example.
@@ -1383,11 +1364,11 @@ Calico is used here as an example.
 {{#tabs name:"tab-deploy-cni" tabs:"Azure,vcluster,KubeVirt,others..."}}
 {{#tab Azure}}
 
-Install the official Calico Helm chart on the workload cluster:
+Azure [does not currently support Calico networking](https://docs.projectcalico.org/reference/public-cloud/azure). As a workaround, it is recommended that Azure clusters use the Calico spec below that uses VXLAN.
 
 ```bash
-helm repo add projectcalico https://docs.tigera.io/calico/charts --kubeconfig=./capi-quickstart.kubeconfig && \
-helm install calico projectcalico/tigera-operator --kubeconfig=./capi-quickstart.kubeconfig -f https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-azure/main/templates/addons/calico/values.yaml --namespace tigera-operator --create-namespace
+kubectl --kubeconfig=./capi-quickstart.kubeconfig \
+  apply -f https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-azure/main/templates/addons/calico.yaml
 ```
 
 After a short while, our nodes should be running and in `Ready` state,
@@ -1471,12 +1452,12 @@ If the nodes don't become ready after a long period, read the pods in the `kube-
 kubectl --kubeconfig=./capi-quickstart.kubeconfig get pod -n kube-system
 ```
 
-If the Calico pods are in image pull error state (`ErrImagePull`), it's probably because of the Docker Hub pull rate limit.
-We can try to fix that by adding a secret with our Docker Hub credentials, and use it;
+If the Calico pods are in image pull error state (`ErrImagePull`), it's probably because of the docker hub pull rate limit.
+We can try to fix that by adding a secret with our docker hub credentials, and use it;
 see [here](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials)
 for details.
 
-First, create the secret. Please notice the Docker config file path, and adjust it to your local setting.
+First, create the secret. Please notice the docker config file path, and adjust it to your local setting.
 ```bash
 kubectl --kubeconfig=./capi-quickstart.kubeconfig create secret generic docker-creds \
     --from-file=.dockerconfigjson=<YOUR DOCKER CONFIG FILE PATH> \
@@ -1583,7 +1564,6 @@ See the [clusterctl] documentation for more detail about clusterctl supported ac
 [clusterctl]: ../clusterctl/overview.md
 [Docker]: https://www.docker.com/
 [GCP provider]: https://github.com/kubernetes-sigs/cluster-api-provider-gcp
-[Helm]: https://helm.sh/docs/intro/install/
 [Hetzner provider]: https://github.com/syself/cluster-api-provider-hetzner
 [IBM Cloud provider]: https://github.com/kubernetes-sigs/cluster-api-provider-ibmcloud
 [infrastructure provider]: ../reference/glossary.md#infrastructure-provider
diff --git a/docs/book/src/user/troubleshooting.md b/docs/book/src/user/troubleshooting.md
index 225a058a6..599336ff4 100644
--- a/docs/book/src/user/troubleshooting.md
+++ b/docs/book/src/user/troubleshooting.md
@@ -46,7 +46,7 @@ In the example above we can see that the Machine `capi-quickstart-6587k-xtvnz` h
 
 To investigate why a machine fails to start you can inspect the conditions of the objects using `clusterctl describe --show-conditions all cluster capi-quickstart`. You can get more detailed information about the status of the machines using `kubectl describe machines`.
 
-To inspect the underlying infrastructure - in this case Docker containers acting as Machines - you can access the logs using `docker logs <MACHINE-NAME>`. For example:
+To inspect the underlying infrastructure - in this case docker containers acting as Machines - you can access the logs using `docker logs <MACHINE-NAME>`. For example:
 
 ```shell
 docker logs capi-quickstart-6587k-xtvnz
@@ -109,7 +109,7 @@ provisioning might be stuck:
  
 1. if there are stopped containers on your machine from previous runs. Clean unused containers with [docker rm -f ](https://docs.docker.com/engine/reference/commandline/rm/). 
 
-2. if the Docker space on your disk is being exhausted 
+2. if the docker space on your disk is being exhausted 
     * Run [docker system df](https://docs.docker.com/engine/reference/commandline/system_df/) to inspect the disk space consumed by Docker resources.
     * Run [docker system prune --volumes](https://docs.docker.com/engine/reference/commandline/system_prune/) to prune dangling images, containers, volumes and networks.
 
@@ -132,7 +132,7 @@ This error was also observed in Docker Desktop 4.3 and 4.4 on MacOS. It can be r
 
 [The upstream issue for this error is closed as of the release of Docker 4.5.0](https://github.com/docker/for-mac/issues/6071)
 
-Note: The below workaround is not recommended unless upgrade or downgrade cannot be performed.
+Note: The below workaround is not recommended unless upgrade or downgrade can not be performed.
 
 If using a version of Docker Desktop for Mac 4.3 or 4.4, the following workaround can be used:
 
diff --git a/exp/internal/controllers/machinepool_controller_noderef.go b/exp/internal/controllers/machinepool_controller_noderef.go
index 1d680ed05..275027b0b 100644
--- a/exp/internal/controllers/machinepool_controller_noderef.go
+++ b/exp/internal/controllers/machinepool_controller_noderef.go
@@ -30,7 +30,6 @@ import (
 	"sigs.k8s.io/cluster-api/controllers/noderefutil"
 	"sigs.k8s.io/cluster-api/controllers/remote"
 	expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
-	"sigs.k8s.io/cluster-api/internal/util/taints"
 	"sigs.k8s.io/cluster-api/util"
 	"sigs.k8s.io/cluster-api/util/annotations"
 	"sigs.k8s.io/cluster-api/util/conditions"
@@ -111,10 +110,9 @@ func (r *MachinePoolReconciler) reconcileNodeRefs(ctx context.Context, cluster *
 			clusterv1.OwnerKindAnnotation:        mp.Kind,
 			clusterv1.OwnerNameAnnotation:        mp.Name,
 		}
-		// Add annotations and drop NodeUninitializedTaint.
-		if annotations.AddAnnotations(node, desired) || taints.RemoveNodeTaint(node, clusterv1.NodeUninitializedTaint) {
+		if annotations.AddAnnotations(node, desired) {
 			if err := patchHelper.Patch(ctx, node); err != nil {
-				log.V(2).Info("Failed patch node to set annotations and drop taints", "err", err, "node name", node.Name)
+				log.V(2).Info("Failed patch node to set annotations", "err", err, "node name", node.Name)
 				return ctrl.Result{}, err
 			}
 		}
diff --git a/go.mod b/go.mod
index 94dcb95a0..154df1398 100644
--- a/go.mod
+++ b/go.mod
@@ -20,8 +20,8 @@ require (
 	github.com/google/go-github/v48 v48.2.0
 	github.com/google/gofuzz v1.2.0
 	github.com/mattn/go-runewidth v0.0.14 // indirect
-	github.com/onsi/ginkgo/v2 v2.9.0
-	github.com/onsi/gomega v1.27.2
+	github.com/onsi/ginkgo/v2 v2.8.4
+	github.com/onsi/gomega v1.27.1
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/cobra v1.6.1
 	github.com/spf13/pflag v1.0.5
@@ -29,8 +29,8 @@ require (
 	github.com/valyala/fastjson v1.6.4
 	go.etcd.io/etcd/api/v3 v3.5.6
 	go.etcd.io/etcd/client/v3 v3.5.6
-	golang.org/x/net v0.8.0 // indirect
-	golang.org/x/oauth2 v0.6.0
+	golang.org/x/net v0.7.0 // indirect
+	golang.org/x/oauth2 v0.5.0
 	google.golang.org/grpc v1.52.0
 	k8s.io/api v0.26.1
 	k8s.io/apiextensions-apiserver v0.26.1
@@ -123,9 +123,9 @@ require (
 	go.uber.org/zap v1.24.0 // indirect
 	go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
 	golang.org/x/crypto v0.3.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/term v0.6.0 // indirect
-	golang.org/x/text v0.8.0
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/term v0.5.0 // indirect
+	golang.org/x/text v0.7.0
 	golang.org/x/time v0.3.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0
 	google.golang.org/appengine v1.6.7 // indirect
diff --git a/go.sum b/go.sum
index 5ffb1f8b3..380477913 100644
--- a/go.sum
+++ b/go.sum
@@ -415,10 +415,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
-github.com/onsi/ginkgo/v2 v2.9.0 h1:Tugw2BKlNHTMfG+CheOITkYvk4LAh6MFOvikhGVnhE8=
-github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk=
-github.com/onsi/gomega v1.27.2 h1:SKU0CXeKE/WVgIV1T61kSa3+IRE8Ekrv9rdXDwwTqnY=
-github.com/onsi/gomega v1.27.2/go.mod h1:5mR3phAHpkAVIDkHEUBY6HGVsU+cpcEscrGPB4oPlZI=
+github.com/onsi/ginkgo/v2 v2.8.4 h1:gf5mIQ8cLFieruNLAdgijHF1PYfLphKm2dxxcUtcqK0=
+github.com/onsi/ginkgo/v2 v2.8.4/go.mod h1:427dEDQZkDKsBvCjc2A/ZPefhKxsTTrsQegMlayL730=
+github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754=
+github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@@ -682,8 +682,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -695,8 +695,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
-golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
+golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
+golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -767,13 +767,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -784,8 +784,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/hack/tools/go.mod b/hack/tools/go.mod
index 6fdc937fe..c79ad1bf7 100644
--- a/hack/tools/go.mod
+++ b/hack/tools/go.mod
@@ -108,7 +108,7 @@ require (
 	github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
 	github.com/morikuni/aec v1.0.0 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
-	github.com/onsi/gomega v1.27.2 // indirect
+	github.com/onsi/gomega v1.27.1 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
@@ -131,12 +131,12 @@ require (
 	go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
 	golang.org/x/crypto v0.5.0 // indirect
 	golang.org/x/mod v0.8.0 // indirect
-	golang.org/x/net v0.8.0 // indirect
-	golang.org/x/oauth2 v0.6.0 // indirect
+	golang.org/x/net v0.7.0 // indirect
+	golang.org/x/oauth2 v0.5.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/term v0.6.0 // indirect
-	golang.org/x/text v0.8.0 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/term v0.5.0 // indirect
+	golang.org/x/text v0.7.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
diff --git a/hack/tools/go.sum b/hack/tools/go.sum
index da33661c1..e824e1b3c 100644
--- a/hack/tools/go.sum
+++ b/hack/tools/go.sum
@@ -425,9 +425,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo/v2 v2.9.0 h1:Tugw2BKlNHTMfG+CheOITkYvk4LAh6MFOvikhGVnhE8=
-github.com/onsi/gomega v1.27.2 h1:SKU0CXeKE/WVgIV1T61kSa3+IRE8Ekrv9rdXDwwTqnY=
-github.com/onsi/gomega v1.27.2/go.mod h1:5mR3phAHpkAVIDkHEUBY6HGVsU+cpcEscrGPB4oPlZI=
+github.com/onsi/ginkgo/v2 v2.8.4 h1:gf5mIQ8cLFieruNLAdgijHF1PYfLphKm2dxxcUtcqK0=
+github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754=
+github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
@@ -671,8 +671,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -684,8 +684,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
-golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
+golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
+golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -758,13 +758,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -775,8 +775,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/internal/controllers/machine/machine_controller_noderef.go b/internal/controllers/machine/machine_controller_noderef.go
index 89ac0a2df..20b83e39d 100644
--- a/internal/controllers/machine/machine_controller_noderef.go
+++ b/internal/controllers/machine/machine_controller_noderef.go
@@ -34,7 +34,6 @@ import (
 	"sigs.k8s.io/cluster-api/api/v1beta1/index"
 	"sigs.k8s.io/cluster-api/controllers/noderefutil"
 	"sigs.k8s.io/cluster-api/internal/util/ssa"
-	"sigs.k8s.io/cluster-api/internal/util/taints"
 	"sigs.k8s.io/cluster-api/util"
 	"sigs.k8s.io/cluster-api/util/annotations"
 	"sigs.k8s.io/cluster-api/util/conditions"
@@ -131,15 +130,6 @@ func (r *Reconciler) reconcileNode(ctx context.Context, cluster *clusterv1.Clust
 	if err != nil {
 		return ctrl.Result{}, errors.Wrap(err, "failed to apply labels to Node")
 	}
-	// Update `node` with the new version of the object.
-	if err := r.Client.Scheme().Convert(updatedNode, node, nil); err != nil {
-		return ctrl.Result{}, errors.Wrapf(err, "failed to convert node to structured object %s", klog.KObj(node))
-	}
-
-	// Reconcile node taints
-	if err := r.reconcileNodeTaints(ctx, remoteClient, node); err != nil {
-		return ctrl.Result{}, errors.Wrapf(err, "failed to reconcile taints on Node %s", klog.KObj(node))
-	}
 
 	// Do the remaining node health checks, then set the node health to true if all checks pass.
 	status, message := summarizeNodeConditions(node)
@@ -268,17 +258,3 @@ func (r *Reconciler) getNode(ctx context.Context, c client.Reader, providerID *n
 
 	return &nodeList.Items[0], nil
 }
-
-func (r *Reconciler) reconcileNodeTaints(ctx context.Context, remoteClient client.Client, node *corev1.Node) error {
-	patchHelper, err := patch.NewHelper(node, remoteClient)
-	if err != nil {
-		return errors.Wrapf(err, "failed to create patch helper for Node %s", klog.KObj(node))
-	}
-	// Drop the NodeUninitializedTaint taint on the node.
-	if taints.RemoveNodeTaint(node, clusterv1.NodeUninitializedTaint) {
-		if err := patchHelper.Patch(ctx, node); err != nil {
-			return errors.Wrapf(err, "failed to patch Node %s to modify taints", klog.KObj(node))
-		}
-	}
-	return nil
-}
diff --git a/internal/controllers/machinedeployment/machinedeployment_controller.go b/internal/controllers/machinedeployment/machinedeployment_controller.go
index 7e193299d..20a212497 100644
--- a/internal/controllers/machinedeployment/machinedeployment_controller.go
+++ b/internal/controllers/machinedeployment/machinedeployment_controller.go
@@ -172,9 +172,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
 	return result, err
 }
 
-func patchMachineDeployment(ctx context.Context, patchHelper *patch.Helper, md *clusterv1.MachineDeployment, options ...patch.Option) error {
+func patchMachineDeployment(ctx context.Context, patchHelper *patch.Helper, d *clusterv1.MachineDeployment, options ...patch.Option) error {
 	// Always update the readyCondition by summarizing the state of other conditions.
-	conditions.SetSummary(md,
+	conditions.SetSummary(d,
 		conditions.WithConditions(
 			clusterv1.MachineDeploymentAvailableCondition,
 		),
@@ -187,29 +187,29 @@ func patchMachineDeployment(ctx context.Context, patchHelper *patch.Helper, md *
 			clusterv1.MachineDeploymentAvailableCondition,
 		}},
 	)
-	return patchHelper.Patch(ctx, md, options...)
+	return patchHelper.Patch(ctx, d, options...)
 }
 
-func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, md *clusterv1.MachineDeployment) (ctrl.Result, error) {
+func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, d *clusterv1.MachineDeployment) (ctrl.Result, error) {
 	log := ctrl.LoggerFrom(ctx)
 	log.V(4).Info("Reconcile MachineDeployment")
 
 	// Reconcile and retrieve the Cluster object.
-	if md.Labels == nil {
-		md.Labels = make(map[string]string)
+	if d.Labels == nil {
+		d.Labels = make(map[string]string)
 	}
-	if md.Spec.Selector.MatchLabels == nil {
-		md.Spec.Selector.MatchLabels = make(map[string]string)
+	if d.Spec.Selector.MatchLabels == nil {
+		d.Spec.Selector.MatchLabels = make(map[string]string)
 	}
-	if md.Spec.Template.Labels == nil {
-		md.Spec.Template.Labels = make(map[string]string)
+	if d.Spec.Template.Labels == nil {
+		d.Spec.Template.Labels = make(map[string]string)
 	}
 
-	md.Labels[clusterv1.ClusterNameLabel] = md.Spec.ClusterName
+	d.Labels[clusterv1.ClusterNameLabel] = d.Spec.ClusterName
 
 	// Set the MachineDeployment as directly owned by the Cluster (if not already present).
-	if r.shouldAdopt(md) {
-		md.OwnerReferences = util.EnsureOwnerRef(md.OwnerReferences, metav1.OwnerReference{
+	if r.shouldAdopt(d) {
+		d.OwnerReferences = util.EnsureOwnerRef(d.OwnerReferences, metav1.OwnerReference{
 			APIVersion: clusterv1.GroupVersion.String(),
 			Kind:       "Cluster",
 			Name:       cluster.Name,
@@ -219,17 +219,17 @@ func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster,
 	}
 
 	// Make sure to reconcile the external infrastructure reference.
-	if err := reconcileExternalTemplateReference(ctx, r.Client, cluster, &md.Spec.Template.Spec.InfrastructureRef); err != nil {
+	if err := reconcileExternalTemplateReference(ctx, r.Client, cluster, &d.Spec.Template.Spec.InfrastructureRef); err != nil {
 		return ctrl.Result{}, err
 	}
 	// Make sure to reconcile the external bootstrap reference, if any.
-	if md.Spec.Template.Spec.Bootstrap.ConfigRef != nil {
-		if err := reconcileExternalTemplateReference(ctx, r.Client, cluster, md.Spec.Template.Spec.Bootstrap.ConfigRef); err != nil {
+	if d.Spec.Template.Spec.Bootstrap.ConfigRef != nil {
+		if err := reconcileExternalTemplateReference(ctx, r.Client, cluster, d.Spec.Template.Spec.Bootstrap.ConfigRef); err != nil {
 			return ctrl.Result{}, err
 		}
 	}
 
-	msList, err := r.getMachineSetsForDeployment(ctx, md)
+	msList, err := r.getMachineSetsForDeployment(ctx, d)
 	if err != nil {
 		return ctrl.Result{}, err
 	}
@@ -241,7 +241,7 @@ func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster,
 	// to all MachineSets created by a MachineDeployment or if a user manually removed the label.
 	for idx := range msList {
 		machineSet := msList[idx]
-		if name, ok := machineSet.Labels[clusterv1.MachineDeploymentNameLabel]; ok && name == md.Name {
+		if name, ok := machineSet.Labels[clusterv1.MachineDeploymentNameLabel]; ok && name == d.Name {
 			continue
 		}
 
@@ -249,7 +249,7 @@ func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster,
 		if err != nil {
 			return ctrl.Result{}, errors.Wrapf(err, "failed to apply %s label to MachineSet %q", clusterv1.MachineDeploymentNameLabel, machineSet.Name)
 		}
-		machineSet.Labels[clusterv1.MachineDeploymentNameLabel] = md.Name
+		machineSet.Labels[clusterv1.MachineDeploymentNameLabel] = d.Name
 		if err := helper.Patch(ctx, machineSet); err != nil {
 			return ctrl.Result{}, errors.Wrapf(err, "failed to apply %s label to MachineSet %q", clusterv1.MachineDeploymentNameLabel, machineSet.Name)
 		}
@@ -268,35 +268,35 @@ func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster,
 		}
 	}
 
-	if md.Spec.Paused {
-		return ctrl.Result{}, r.sync(ctx, md, msList)
+	if d.Spec.Paused {
+		return ctrl.Result{}, r.sync(ctx, d, msList)
 	}
 
-	if md.Spec.Strategy == nil {
+	if d.Spec.Strategy == nil {
 		return ctrl.Result{}, errors.Errorf("missing MachineDeployment strategy")
 	}
 
-	if md.Spec.Strategy.Type == clusterv1.RollingUpdateMachineDeploymentStrategyType {
-		if md.Spec.Strategy.RollingUpdate == nil {
-			return ctrl.Result{}, errors.Errorf("missing MachineDeployment settings for strategy type: %s", md.Spec.Strategy.Type)
+	if d.Spec.Strategy.Type == clusterv1.RollingUpdateMachineDeploymentStrategyType {
+		if d.Spec.Strategy.RollingUpdate == nil {
+			return ctrl.Result{}, errors.Errorf("missing MachineDeployment settings for strategy type: %s", d.Spec.Strategy.Type)
 		}
-		return ctrl.Result{}, r.rolloutRolling(ctx, md, msList)
+		return ctrl.Result{}, r.rolloutRolling(ctx, d, msList)
 	}
 
-	if md.Spec.Strategy.Type == clusterv1.OnDeleteMachineDeploymentStrategyType {
-		return ctrl.Result{}, r.rolloutOnDelete(ctx, md, msList)
+	if d.Spec.Strategy.Type == clusterv1.OnDeleteMachineDeploymentStrategyType {
+		return ctrl.Result{}, r.rolloutOnDelete(ctx, d, msList)
 	}
 
-	return ctrl.Result{}, errors.Errorf("unexpected deployment strategy type: %s", md.Spec.Strategy.Type)
+	return ctrl.Result{}, errors.Errorf("unexpected deployment strategy type: %s", d.Spec.Strategy.Type)
 }
 
 // getMachineSetsForDeployment returns a list of MachineSets associated with a MachineDeployment.
-func (r *Reconciler) getMachineSetsForDeployment(ctx context.Context, md *clusterv1.MachineDeployment) ([]*clusterv1.MachineSet, error) {
+func (r *Reconciler) getMachineSetsForDeployment(ctx context.Context, d *clusterv1.MachineDeployment) ([]*clusterv1.MachineSet, error) {
 	log := ctrl.LoggerFrom(ctx)
 
 	// List all MachineSets to find those we own but that no longer match our selector.
 	machineSets := &clusterv1.MachineSetList{}
-	if err := r.Client.List(ctx, machineSets, client.InNamespace(md.Namespace)); err != nil {
+	if err := r.Client.List(ctx, machineSets, client.InNamespace(d.Namespace)); err != nil {
 		return nil, err
 	}
 
@@ -304,7 +304,7 @@ func (r *Reconciler) getMachineSetsForDeployment(ctx context.Context, md *cluste
 	for idx := range machineSets.Items {
 		ms := &machineSets.Items[idx]
 		log.WithValues("MachineSet", klog.KObj(ms))
-		selector, err := metav1.LabelSelectorAsSelector(&md.Spec.Selector)
+		selector, err := metav1.LabelSelectorAsSelector(&d.Spec.Selector)
 		if err != nil {
 			log.Error(err, "Skipping MachineSet, failed to get label selector from spec selector")
 			continue
@@ -317,23 +317,23 @@ func (r *Reconciler) getMachineSetsForDeployment(ctx context.Context, md *cluste
 		}
 
 		// Skip this MachineSet unless either selector matches or it has a controller ref pointing to this MachineDeployment
-		if !selector.Matches(labels.Set(ms.Labels)) && !metav1.IsControlledBy(ms, md) {
+		if !selector.Matches(labels.Set(ms.Labels)) && !metav1.IsControlledBy(ms, d) {
 			log.V(4).Info("Skipping MachineSet, label mismatch")
 			continue
 		}
 
 		// Attempt to adopt MachineSet if it meets previous conditions and it has no controller references.
 		if metav1.GetControllerOf(ms) == nil {
-			if err := r.adoptOrphan(ctx, md, ms); err != nil {
+			if err := r.adoptOrphan(ctx, d, ms); err != nil {
 				log.Error(err, "Failed to adopt MachineSet into MachineDeployment")
-				r.recorder.Eventf(md, corev1.EventTypeWarning, "FailedAdopt", "Failed to adopt MachineSet %q: %v", ms.Name, err)
+				r.recorder.Eventf(d, corev1.EventTypeWarning, "FailedAdopt", "Failed to adopt MachineSet %q: %v", ms.Name, err)
 				continue
 			}
 			log.Info("Adopted MachineSet into MachineDeployment")
-			r.recorder.Eventf(md, corev1.EventTypeNormal, "SuccessfulAdopt", "Adopted MachineSet %q", ms.Name)
+			r.recorder.Eventf(d, corev1.EventTypeNormal, "SuccessfulAdopt", "Adopted MachineSet %q", ms.Name)
 		}
 
-		if !metav1.IsControlledBy(ms, md) {
+		if !metav1.IsControlledBy(ms, d) {
 			continue
 		}
 
diff --git a/internal/controllers/machinedeployment/machinedeployment_rolling.go b/internal/controllers/machinedeployment/machinedeployment_rolling.go
index ffc7acc19..a40dd5c2f 100644
--- a/internal/controllers/machinedeployment/machinedeployment_rolling.go
+++ b/internal/controllers/machinedeployment/machinedeployment_rolling.go
@@ -30,8 +30,8 @@ import (
 )
 
 // rolloutRolling implements the logic for rolling a new MachineSet.
-func (r *Reconciler) rolloutRolling(ctx context.Context, md *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet) error {
-	newMS, oldMSs, err := r.getAllMachineSetsAndSyncRevision(ctx, md, msList, true)
+func (r *Reconciler) rolloutRolling(ctx context.Context, d *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet) error {
+	newMS, oldMSs, err := r.getAllMachineSetsAndSyncRevision(ctx, d, msList, true)
 	if err != nil {
 		return err
 	}
@@ -46,25 +46,25 @@ func (r *Reconciler) rolloutRolling(ctx context.Context, md *clusterv1.MachineDe
 	allMSs := append(oldMSs, newMS)
 
 	// Scale up, if we can.
-	if err := r.reconcileNewMachineSet(ctx, allMSs, newMS, md); err != nil {
+	if err := r.reconcileNewMachineSet(ctx, allMSs, newMS, d); err != nil {
 		return err
 	}
 
-	if err := r.syncDeploymentStatus(allMSs, newMS, md); err != nil {
+	if err := r.syncDeploymentStatus(allMSs, newMS, d); err != nil {
 		return err
 	}
 
 	// Scale down, if we can.
-	if err := r.reconcileOldMachineSets(ctx, allMSs, oldMSs, newMS, md); err != nil {
+	if err := r.reconcileOldMachineSets(ctx, allMSs, oldMSs, newMS, d); err != nil {
 		return err
 	}
 
-	if err := r.syncDeploymentStatus(allMSs, newMS, md); err != nil {
+	if err := r.syncDeploymentStatus(allMSs, newMS, d); err != nil {
 		return err
 	}
 
-	if mdutil.DeploymentComplete(md, &md.Status) {
-		if err := r.cleanupDeployment(ctx, oldMSs, md); err != nil {
+	if mdutil.DeploymentComplete(d, &d.Status) {
+		if err := r.cleanupDeployment(ctx, oldMSs, d); err != nil {
 			return err
 		}
 	}
diff --git a/internal/controllers/machinedeployment/machinedeployment_rollout_ondelete.go b/internal/controllers/machinedeployment/machinedeployment_rollout_ondelete.go
index 107d65e50..dbe9a9a3b 100644
--- a/internal/controllers/machinedeployment/machinedeployment_rollout_ondelete.go
+++ b/internal/controllers/machinedeployment/machinedeployment_rollout_ondelete.go
@@ -32,8 +32,8 @@ import (
 )
 
 // rolloutOnDelete implements the logic for the OnDelete MachineDeploymentStrategyType.
-func (r *Reconciler) rolloutOnDelete(ctx context.Context, md *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet) error {
-	newMS, oldMSs, err := r.getAllMachineSetsAndSyncRevision(ctx, md, msList, true)
+func (r *Reconciler) rolloutOnDelete(ctx context.Context, d *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet) error {
+	newMS, oldMSs, err := r.getAllMachineSetsAndSyncRevision(ctx, d, msList, true)
 	if err != nil {
 		return err
 	}
@@ -48,25 +48,25 @@ func (r *Reconciler) rolloutOnDelete(ctx context.Context, md *clusterv1.MachineD
 	allMSs := append(oldMSs, newMS)
 
 	// Scale up, if we can.
-	if err := r.reconcileNewMachineSetOnDelete(ctx, allMSs, newMS, md); err != nil {
+	if err := r.reconcileNewMachineSetOnDelete(ctx, allMSs, newMS, d); err != nil {
 		return err
 	}
 
-	if err := r.syncDeploymentStatus(allMSs, newMS, md); err != nil {
+	if err := r.syncDeploymentStatus(allMSs, newMS, d); err != nil {
 		return err
 	}
 
 	// Scale down, if we can.
-	if err := r.reconcileOldMachineSetsOnDelete(ctx, oldMSs, allMSs, md); err != nil {
+	if err := r.reconcileOldMachineSetsOnDelete(ctx, oldMSs, allMSs, d); err != nil {
 		return err
 	}
 
-	if err := r.syncDeploymentStatus(allMSs, newMS, md); err != nil {
+	if err := r.syncDeploymentStatus(allMSs, newMS, d); err != nil {
 		return err
 	}
 
-	if mdutil.DeploymentComplete(md, &md.Status) {
-		if err := r.cleanupDeployment(ctx, oldMSs, md); err != nil {
+	if mdutil.DeploymentComplete(d, &d.Status) {
+		if err := r.cleanupDeployment(ctx, oldMSs, d); err != nil {
 			return err
 		}
 	}
diff --git a/internal/controllers/machinedeployment/machinedeployment_sync.go b/internal/controllers/machinedeployment/machinedeployment_sync.go
index 9bc3640bc..8c05d997b 100644
--- a/internal/controllers/machinedeployment/machinedeployment_sync.go
+++ b/internal/controllers/machinedeployment/machinedeployment_sync.go
@@ -49,13 +49,13 @@ import (
 
 // sync is responsible for reconciling deployments on scaling events or when they
 // are paused.
-func (r *Reconciler) sync(ctx context.Context, md *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet) error {
-	newMS, oldMSs, err := r.getAllMachineSetsAndSyncRevision(ctx, md, msList, false)
+func (r *Reconciler) sync(ctx context.Context, d *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet) error {
+	newMS, oldMSs, err := r.getAllMachineSetsAndSyncRevision(ctx, d, msList, false)
 	if err != nil {
 		return err
 	}
 
-	if err := r.scale(ctx, md, newMS, oldMSs); err != nil {
+	if err := r.scale(ctx, d, newMS, oldMSs); err != nil {
 		// If we get an error while trying to scale, the deployment will be requeued
 		// so we can abort this resync
 		return err
@@ -65,7 +65,7 @@ func (r *Reconciler) sync(ctx context.Context, md *clusterv1.MachineDeployment,
 	// // TODO: Clean up the deployment when it's paused and no rollback is in flight.
 	//
 	allMSs := append(oldMSs, newMS)
-	return r.syncDeploymentStatus(allMSs, newMS, md)
+	return r.syncDeploymentStatus(allMSs, newMS, d)
 }
 
 // getAllMachineSetsAndSyncRevision returns all the machine sets for the provided deployment (new and all old), with new MS's and deployment's revision updated.
@@ -80,11 +80,11 @@ func (r *Reconciler) sync(ctx context.Context, md *clusterv1.MachineDeployment,
 //
 // Note that currently the deployment controller is using caches to avoid querying the server for reads.
 // This may lead to stale reads of machine sets, thus incorrect deployment status.
-func (r *Reconciler) getAllMachineSetsAndSyncRevision(ctx context.Context, md *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet, createIfNotExisted bool) (*clusterv1.MachineSet, []*clusterv1.MachineSet, error) {
-	_, allOldMSs := mdutil.FindOldMachineSets(md, msList)
+func (r *Reconciler) getAllMachineSetsAndSyncRevision(ctx context.Context, d *clusterv1.MachineDeployment, msList []*clusterv1.MachineSet, createIfNotExisted bool) (*clusterv1.MachineSet, []*clusterv1.MachineSet, error) {
+	_, allOldMSs := mdutil.FindOldMachineSets(d, msList)
 
 	// Get new machine set with the updated revision number
-	newMS, err := r.getNewMachineSet(ctx, md, msList, allOldMSs, createIfNotExisted)
+	newMS, err := r.getNewMachineSet(ctx, d, msList, allOldMSs, createIfNotExisted)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -95,7 +95,7 @@ func (r *Reconciler) getAllMachineSetsAndSyncRevision(ctx context.Context, md *c
 // Returns a MachineSet that matches the intent of the given MachineDeployment.
 // If there does not exist such a MachineSet and createIfNotExisted is true, create a new MachineSet.
 // If there is already such a MachineSet, update it to propagate in-place mutable fields from the MachineDeployment.
-func (r *Reconciler) getNewMachineSet(ctx context.Context, md *clusterv1.MachineDeployment, msList, oldMSs []*clusterv1.MachineSet, createIfNotExists bool) (*clusterv1.MachineSet, error) {
+func (r *Reconciler) getNewMachineSet(ctx context.Context, d *clusterv1.MachineDeployment, msList, oldMSs []*clusterv1.MachineSet, createIfNotExists bool) (*clusterv1.MachineSet, error) {
 	// Try to find a MachineSet which matches the MachineDeployments intent, while ignore diffs between
 	// the in-place mutable fields.
 	// If we find a matching MachineSet we just update it to propagate any changes to the in-place mutable
@@ -103,19 +103,19 @@ func (r *Reconciler) getNewMachineSet(ctx context.Context, md *clusterv1.Machine
 	// If we don't find a matching MachineSet, we need a rollout and thus create a new MachineSet.
 	// Note: The in-place mutable fields can be just updated inline, because they do not affect the actual machines
 	// themselves (i.e. the infrastructure and the software running on the Machines not the Machine object).
-	matchingMS := mdutil.FindNewMachineSet(md, msList)
+	matchingMS := mdutil.FindNewMachineSet(d, msList)
 
 	// If there is a MachineSet that matches the intent of the MachineDeployment, update the MachineSet
 	// to propagate all in-place mutable fields from MachineDeployment to the MachineSet.
 	if matchingMS != nil {
-		updatedMS, err := r.updateMachineSet(ctx, md, matchingMS, oldMSs)
+		updatedMS, err := r.updateMachineSet(ctx, d, matchingMS, oldMSs)
 		if err != nil {
 			return nil, err
 		}
 
 		// Ensure MachineDeployment has the latest MachineSet revision in its revision annotation.
-		err = r.updateMachineDeployment(ctx, md, func(innerDeployment *clusterv1.MachineDeployment) {
-			mdutil.SetDeploymentRevision(md, updatedMS.Annotations[clusterv1.RevisionAnnotation])
+		err = r.updateMachineDeployment(ctx, d, func(innerDeployment *clusterv1.MachineDeployment) {
+			mdutil.SetDeploymentRevision(d, updatedMS.Annotations[clusterv1.RevisionAnnotation])
 		})
 		if err != nil {
 			return nil, errors.Wrap(err, "failed to update revision annotation on MachineDeployment")
@@ -128,14 +128,14 @@ func (r *Reconciler) getNewMachineSet(ctx context.Context, md *clusterv1.Machine
 	}
 
 	// Create a new MachineSet and wait until the new MachineSet exists in the cache.
-	newMS, err := r.createMachineSetAndWait(ctx, md, oldMSs)
+	newMS, err := r.createMachineSetAndWait(ctx, d, oldMSs)
 	if err != nil {
 		return nil, err
 	}
 
 	// Ensure MachineDeployment has the latest MachineSet revision in its revision annotation.
-	err = r.updateMachineDeployment(ctx, md, func(innerDeployment *clusterv1.MachineDeployment) {
-		mdutil.SetDeploymentRevision(md, newMS.Annotations[clusterv1.RevisionAnnotation])
+	err = r.updateMachineDeployment(ctx, d, func(innerDeployment *clusterv1.MachineDeployment) {
+		mdutil.SetDeploymentRevision(d, newMS.Annotations[clusterv1.RevisionAnnotation])
 	})
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to update revision annotation on MachineDeployment")
@@ -483,17 +483,17 @@ func (r *Reconciler) scale(ctx context.Context, deployment *clusterv1.MachineDep
 }
 
 // syncDeploymentStatus checks if the status is up-to-date and sync it if necessary.
-func (r *Reconciler) syncDeploymentStatus(allMSs []*clusterv1.MachineSet, newMS *clusterv1.MachineSet, md *clusterv1.MachineDeployment) error {
-	md.Status = calculateStatus(allMSs, newMS, md)
+func (r *Reconciler) syncDeploymentStatus(allMSs []*clusterv1.MachineSet, newMS *clusterv1.MachineSet, d *clusterv1.MachineDeployment) error {
+	d.Status = calculateStatus(allMSs, newMS, d)
 
-	// minReplicasNeeded will be equal to md.Spec.Replicas when the strategy is not RollingUpdateMachineDeploymentStrategyType.
-	minReplicasNeeded := *(md.Spec.Replicas) - mdutil.MaxUnavailable(*md)
+	// minReplicasNeeded will be equal to d.Spec.Replicas when the strategy is not RollingUpdateMachineDeploymentStrategyType.
+	minReplicasNeeded := *(d.Spec.Replicas) - mdutil.MaxUnavailable(*d)
 
-	if md.Status.AvailableReplicas >= minReplicasNeeded {
+	if d.Status.AvailableReplicas >= minReplicasNeeded {
 		// NOTE: The structure of calculateStatus() does not allow us to update the machinedeployment directly, we can only update the status obj it returns. Ideally, we should change calculateStatus() --> updateStatus() to be consistent with the rest of the code base, until then, we update conditions here.
-		conditions.MarkTrue(md, clusterv1.MachineDeploymentAvailableCondition)
+		conditions.MarkTrue(d, clusterv1.MachineDeploymentAvailableCondition)
 	} else {
-		conditions.MarkFalse(md, clusterv1.MachineDeploymentAvailableCondition, clusterv1.WaitingForAvailableMachinesReason, clusterv1.ConditionSeverityWarning, "Minimum availability requires %d replicas, current %d available", minReplicasNeeded, md.Status.AvailableReplicas)
+		conditions.MarkFalse(d, clusterv1.MachineDeploymentAvailableCondition, clusterv1.WaitingForAvailableMachinesReason, clusterv1.ConditionSeverityWarning, "Minimum availability requires %d replicas, current %d available", minReplicasNeeded, d.Status.AvailableReplicas)
 	}
 	return nil
 }
@@ -641,15 +641,15 @@ func (r *Reconciler) cleanupDeployment(ctx context.Context, oldMSs []*clusterv1.
 	return nil
 }
 
-func (r *Reconciler) updateMachineDeployment(ctx context.Context, md *clusterv1.MachineDeployment, modify func(*clusterv1.MachineDeployment)) error {
-	return updateMachineDeployment(ctx, r.Client, md, modify)
+func (r *Reconciler) updateMachineDeployment(ctx context.Context, d *clusterv1.MachineDeployment, modify func(*clusterv1.MachineDeployment)) error {
+	return updateMachineDeployment(ctx, r.Client, d, modify)
 }
 
 // We have this as standalone variant to be able to use it from the tests.
-func updateMachineDeployment(ctx context.Context, c client.Client, md *clusterv1.MachineDeployment, modify func(*clusterv1.MachineDeployment)) error {
-	mdObjectKey := util.ObjectKey(md)
+func updateMachineDeployment(ctx context.Context, c client.Client, d *clusterv1.MachineDeployment, modify func(*clusterv1.MachineDeployment)) error {
+	mdObjectKey := util.ObjectKey(d)
 	return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
-		// Note: We intentionally don't re-use the passed in MachineDeployment md here as that would
+		// Note: We intentionally don't re-use the passed in MachineDeployment d here as that would
 		// overwrite any local changes we might have previously made to the MachineDeployment with the version
 		// we get here from the apiserver.
 		md := &clusterv1.MachineDeployment{}
diff --git a/internal/controllers/machinedeployment/mdutil/util.go b/internal/controllers/machinedeployment/mdutil/util.go
index b8e672cd9..c49574541 100644
--- a/internal/controllers/machinedeployment/mdutil/util.go
+++ b/internal/controllers/machinedeployment/mdutil/util.go
@@ -322,12 +322,12 @@ func MaxSurge(deployment clusterv1.MachineDeployment) int32 {
 // GetProportion will estimate the proportion for the provided machine set using 1. the current size
 // of the parent deployment, 2. the replica count that needs be added on the machine sets of the
 // deployment, and 3. the total replicas added in the machine sets of the deployment so far.
-func GetProportion(ms *clusterv1.MachineSet, md clusterv1.MachineDeployment, deploymentReplicasToAdd, deploymentReplicasAdded int32, logger logr.Logger) int32 {
+func GetProportion(ms *clusterv1.MachineSet, d clusterv1.MachineDeployment, deploymentReplicasToAdd, deploymentReplicasAdded int32, logger logr.Logger) int32 {
 	if ms == nil || *(ms.Spec.Replicas) == 0 || deploymentReplicasToAdd == 0 || deploymentReplicasToAdd == deploymentReplicasAdded {
 		return int32(0)
 	}
 
-	msFraction := getMachineSetFraction(*ms, md, logger)
+	msFraction := getMachineSetFraction(*ms, d, logger)
 	allowed := deploymentReplicasToAdd - deploymentReplicasAdded
 
 	if deploymentReplicasToAdd > 0 {
@@ -344,20 +344,20 @@ func GetProportion(ms *clusterv1.MachineSet, md clusterv1.MachineDeployment, dep
 
 // getMachineSetFraction estimates the fraction of replicas a machine set can have in
 // 1. a scaling event during a rollout or 2. when scaling a paused deployment.
-func getMachineSetFraction(ms clusterv1.MachineSet, md clusterv1.MachineDeployment, logger logr.Logger) int32 {
+func getMachineSetFraction(ms clusterv1.MachineSet, d clusterv1.MachineDeployment, logger logr.Logger) int32 {
 	// If we are scaling down to zero then the fraction of this machine set is its whole size (negative)
-	if *(md.Spec.Replicas) == int32(0) {
+	if *(d.Spec.Replicas) == int32(0) {
 		return -*(ms.Spec.Replicas)
 	}
 
-	deploymentReplicas := *(md.Spec.Replicas) + MaxSurge(md)
+	deploymentReplicas := *(d.Spec.Replicas) + MaxSurge(d)
 	annotatedReplicas, ok := getMaxReplicasAnnotation(&ms, logger)
 	if !ok {
 		// If we cannot find the annotation then fallback to the current deployment size. Note that this
 		// will not be an accurate proportion estimation in case other machine sets have different values
 		// which means that the deployment was scaled at some point but we at least will stay in limits
 		// due to the min-max comparisons in getProportion.
-		annotatedReplicas = md.Status.Replicas
+		annotatedReplicas = d.Status.Replicas
 	}
 
 	// We should never proportionally scale up from zero which means ms.spec.replicas and annotatedReplicas
diff --git a/internal/util/taints/taints.go b/internal/util/taints/taints.go
deleted file mode 100644
index 2d07ce422..000000000
--- a/internal/util/taints/taints.go
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-Copyright 2023 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 taints implements taint helper functions.
-package taints
-
-import (
-	corev1 "k8s.io/api/core/v1"
-)
-
-// RemoveNodeTaint drops the taint from the list of node taints.
-// It returns true if the taints are modified, false otherwise.
-func RemoveNodeTaint(node *corev1.Node, drop corev1.Taint) bool {
-	droppedTaint := false
-	taints := []corev1.Taint{}
-	for _, taint := range node.Spec.Taints {
-		if taint.MatchTaint(&drop) {
-			droppedTaint = true
-			continue
-		}
-		taints = append(taints, taint)
-	}
-	node.Spec.Taints = taints
-	return droppedTaint
-}


Test patch:
diff --git a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller_test.go b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller_test.go
index 54e9304ce..4038c3a16 100644
--- a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller_test.go
+++ b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller_test.go
@@ -24,7 +24,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/blang/semver"
 	ignition "github.com/flatcar/ignition/config/v2_3"
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
@@ -2194,112 +2193,6 @@ func TestKubeadmConfigReconciler_ResolveUsers(t *testing.T) {
 	}
 }
 
-func TestAddNodeUninitializedTaint(t *testing.T) {
-	dummyTaint := corev1.Taint{
-		Key:    "dummy-taint",
-		Value:  "",
-		Effect: corev1.TaintEffectNoSchedule,
-	}
-
-	tests := []struct {
-		name              string
-		nodeRegistration  *bootstrapv1.NodeRegistrationOptions
-		kubernetesVersion semver.Version
-		isControlPlane    bool
-		wantTaints        []corev1.Taint
-	}{
-		{
-			name: "for control plane with version < v1.24.0, if taints is nil it should add the uninitialized and the master taint",
-			nodeRegistration: &bootstrapv1.NodeRegistrationOptions{
-				Taints: nil,
-			},
-			kubernetesVersion: semver.MustParse("1.23.0"),
-			isControlPlane:    true,
-			wantTaints: []corev1.Taint{
-				oldControlPlaneTaint,
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-		{
-			name: "for control plane with version >= v1.24.0 and < v1.25.0, if taints is nil it should add the uninitialized, control-plane and the master taints",
-			nodeRegistration: &bootstrapv1.NodeRegistrationOptions{
-				Taints: nil,
-			},
-			kubernetesVersion: semver.MustParse("1.24.5"),
-			isControlPlane:    true,
-			wantTaints: []corev1.Taint{
-				oldControlPlaneTaint,
-				controlPlaneTaint,
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-		{
-			name: "for control plane with version >= v1.25.0, if taints is nil it should add the uninitialized and the control-plane taint",
-			nodeRegistration: &bootstrapv1.NodeRegistrationOptions{
-				Taints: nil,
-			},
-			kubernetesVersion: semver.MustParse("1.25.0"),
-			isControlPlane:    true,
-			wantTaints: []corev1.Taint{
-				controlPlaneTaint,
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-		{
-			name: "for control plane, if taints is not nil it should only add the uninitialized taint",
-			nodeRegistration: &bootstrapv1.NodeRegistrationOptions{
-				Taints: []corev1.Taint{},
-			},
-			kubernetesVersion: semver.MustParse("1.26.0"),
-			isControlPlane:    true,
-			wantTaints: []corev1.Taint{
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-		{
-			name: "for control plane, if it already has some taints it should add the uninitialized taint",
-			nodeRegistration: &bootstrapv1.NodeRegistrationOptions{
-				Taints: []corev1.Taint{dummyTaint},
-			},
-			kubernetesVersion: semver.MustParse("1.26.0"),
-			isControlPlane:    true,
-			wantTaints: []corev1.Taint{
-				dummyTaint,
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-		{
-			name:              "for worker, it should add the uninitialized taint",
-			nodeRegistration:  &bootstrapv1.NodeRegistrationOptions{},
-			kubernetesVersion: semver.MustParse("1.26.0"),
-			isControlPlane:    false,
-			wantTaints: []corev1.Taint{
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-		{
-			name: "for worker, if it already has some taints it should add the uninitialized taint",
-			nodeRegistration: &bootstrapv1.NodeRegistrationOptions{
-				Taints: []corev1.Taint{dummyTaint},
-			},
-			kubernetesVersion: semver.MustParse("1.26.0"),
-			isControlPlane:    false,
-			wantTaints: []corev1.Taint{
-				dummyTaint,
-				clusterv1.NodeUninitializedTaint,
-			},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			g := NewWithT(t)
-			addNodeUninitializedTaint(tt.nodeRegistration, tt.isControlPlane, tt.kubernetesVersion)
-			g.Expect(tt.nodeRegistration.Taints).To(Equal(tt.wantTaints))
-		})
-	}
-}
-
 // test utils.
 
 // newWorkerMachineForCluster returns a Machine with the passed Cluster's information and a pre-configured name.
diff --git a/docs/book/src/developer/e2e.md b/docs/book/src/developer/e2e.md
index 590ec81dc..94762a200 100644
--- a/docs/book/src/developer/e2e.md
+++ b/docs/book/src/developer/e2e.md
@@ -18,9 +18,9 @@ test specs for the most common Cluster API use cases.
 
 Each E2E test requires a set of artifacts to be available:
 
-- Binaries & Docker images for Kubernetes, CNI, CRI & CSI
-- Manifests & Docker images for the Cluster API core components
-- Manifests & Docker images for the Cluster API infrastructure provider; in most cases
+- Binaries & docker images for Kubernetes, CNI, CRI & CSI
+- Manifests & docker images for the Cluster API core components
+- Manifests & docker images for the Cluster API infrastructure provider; in most cases
   machine images are also required (AMI, OVA etc.)
 - Credentials for the target infrastructure provider
 - Other support tools (e.g. kustomize, gsutil etc.)
diff --git a/docs/book/src/developer/testing.md b/docs/book/src/developer/testing.md
index 07de97689..1d60fec1c 100644
--- a/docs/book/src/developer/testing.md
+++ b/docs/book/src/developer/testing.md
@@ -193,11 +193,11 @@ kind images). This can be done by executing the `./scripts/ci-e2e.sh` script.
 GINKGO_FOCUS="\[PR-Blocking\]" ./scripts/ci-e2e.sh
 ```
 
-Now, the tests can be run in an IDE. The following describes how this can be done in IntelliJ IDEA and VS Code. It should work
+Now, the tests can be run in an IDE. The following describes how this can be done in Intellij IDEA and VS Code. It should work
 roughly the same way in all other IDEs. We assume the `cluster-api` repository has been checked
 out into `/home/user/code/src/sigs.k8s.io/cluster-api`.
 
-#### IntelliJ
+#### Intellij
 
 Create a new run configuration and fill in:
 * Test framework: `gotest`
@@ -555,8 +555,8 @@ In Cluster API Unit and integration test MUST use [go test].
 [Cluster API quick start]: ../user/quick-start.md
 [Cluster API test framework]: https://pkg.go.dev/sigs.k8s.io/cluster-api/test/framework?tab=doc
 [e2e development]: ./e2e.md
-[Ginkgo]: https://onsi.github.io/ginkgo/
-[Gomega]: https://onsi.github.io/gomega/
+[Ginkgo]: http://onsi.github.io/ginkgo/
+[Gomega]: http://onsi.github.io/gomega/
 [go test]: https://golang.org/pkg/testing/
 [controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime
 [envtest]: https://github.com/kubernetes-sigs/controller-runtime/tree/master/pkg/envtest
diff --git a/internal/controllers/machine/machine_controller_noderef_test.go b/internal/controllers/machine/machine_controller_noderef_test.go
index f71d10972..ede053801 100644
--- a/internal/controllers/machine/machine_controller_noderef_test.go
+++ b/internal/controllers/machine/machine_controller_noderef_test.go
@@ -27,7 +27,6 @@ import (
 	"k8s.io/utils/pointer"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
@@ -460,70 +459,3 @@ func TestGetManagedLabels(t *testing.T) {
 	got := getManagedLabels(allLabels)
 	g.Expect(got).To(BeEquivalentTo(managedLabels))
 }
-
-func TestReconcileNodeTaints(t *testing.T) {
-	tests := []struct {
-		name string
-		node *corev1.Node
-	}{
-		{
-			name: "if the node has the uninitialized taint it should be dropped from the node",
-			node: &corev1.Node{
-				ObjectMeta: metav1.ObjectMeta{
-					Name: "test-node-1",
-				},
-				Spec: corev1.NodeSpec{
-					Taints: []corev1.Taint{
-						clusterv1.NodeUninitializedTaint,
-					},
-				},
-			},
-		},
-		{
-			name: "if the node is a control plane and has the uninitialized taint it should be dropped from the node",
-			node: &corev1.Node{
-				ObjectMeta: metav1.ObjectMeta{
-					Name: "test-node-1",
-				},
-				Spec: corev1.NodeSpec{
-					Taints: []corev1.Taint{
-						{
-							Key:    "node-role.kubernetes.io/control-plane",
-							Effect: corev1.TaintEffectNoSchedule,
-						},
-						clusterv1.NodeUninitializedTaint,
-					},
-				},
-			},
-		},
-		{
-			name: "if the node does not have the uninitialized taint it should remain absent from the node",
-			node: &corev1.Node{
-				ObjectMeta: metav1.ObjectMeta{
-					Name: "test-node-1",
-				},
-				Spec: corev1.NodeSpec{
-					Taints: []corev1.Taint{},
-				},
-			},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			g := NewWithT(t)
-			fakeClient := fake.NewClientBuilder().WithObjects(tt.node).WithScheme(fakeScheme).Build()
-			nodeBefore := tt.node.DeepCopy()
-			r := &Reconciler{}
-			g.Expect(r.reconcileNodeTaints(ctx, fakeClient, tt.node)).Should(Succeed())
-			// Verify the NodeUninitializedTaint is dropped.
-			g.Expect(tt.node.Spec.Taints).ShouldNot(ContainElement(clusterv1.NodeUninitializedTaint))
-			// Verify all other taints are same.
-			for _, taint := range nodeBefore.Spec.Taints {
-				if !taint.MatchTaint(&clusterv1.NodeUninitializedTaint) {
-					g.Expect(tt.node.Spec.Taints).Should(ContainElement(taint))
-				}
-			}
-		})
-	}
-}
diff --git a/internal/controllers/machine/suite_test.go b/internal/controllers/machine/suite_test.go
index d8439e520..3143e7699 100644
--- a/internal/controllers/machine/suite_test.go
+++ b/internal/controllers/machine/suite_test.go
@@ -27,7 +27,6 @@ import (
 	. "github.com/onsi/gomega"
 	"github.com/onsi/gomega/types"
 	"github.com/pkg/errors"
-	corev1 "k8s.io/api/core/v1"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -56,7 +55,6 @@ func init() {
 	_ = clientgoscheme.AddToScheme(fakeScheme)
 	_ = clusterv1.AddToScheme(fakeScheme)
 	_ = apiextensionsv1.AddToScheme(fakeScheme)
-	_ = corev1.AddToScheme(fakeScheme)
 }
 
 func TestMain(m *testing.M) {
diff --git a/internal/controllers/machinedeployment/mdutil/util_test.go b/internal/controllers/machinedeployment/mdutil/util_test.go
index 5329b1a65..049f82d27 100644
--- a/internal/controllers/machinedeployment/mdutil/util_test.go
+++ b/internal/controllers/machinedeployment/mdutil/util_test.go
@@ -36,26 +36,26 @@ import (
 	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
 )
 
-func newDControllerRef(md *clusterv1.MachineDeployment) *metav1.OwnerReference {
+func newDControllerRef(d *clusterv1.MachineDeployment) *metav1.OwnerReference {
 	isController := true
 	return &metav1.OwnerReference{
 		APIVersion: "clusters/v1alpha",
 		Kind:       "MachineDeployment",
-		Name:       md.GetName(),
-		UID:        md.GetUID(),
+		Name:       d.GetName(),
+		UID:        d.GetUID(),
 		Controller: &isController,
 	}
 }
 
 // generateMS creates a machine set, with the input deployment's template as its template.
-func generateMS(md clusterv1.MachineDeployment) clusterv1.MachineSet {
-	template := md.Spec.Template.DeepCopy()
+func generateMS(deployment clusterv1.MachineDeployment) clusterv1.MachineSet {
+	template := deployment.Spec.Template.DeepCopy()
 	return clusterv1.MachineSet{
 		ObjectMeta: metav1.ObjectMeta{
 			UID:             randomUID(),
 			Name:            names.SimpleNameGenerator.GenerateName("machineset"),
 			Labels:          template.Labels,
-			OwnerReferences: []metav1.OwnerReference{*newDControllerRef(&md)},
+			OwnerReferences: []metav1.OwnerReference{*newDControllerRef(&deployment)},
 		},
 		Spec: clusterv1.MachineSetSpec{
 			Replicas: new(int32),
@@ -617,32 +617,32 @@ func TestDeploymentComplete(t *testing.T) {
 	tests := []struct {
 		name string
 
-		md *clusterv1.MachineDeployment
+		d *clusterv1.MachineDeployment
 
 		expected bool
 	}{
 		{
 			name: "not complete: min but not all machines become available",
 
-			md:       deployment(5, 5, 5, 4, 1, 0),
+			d:        deployment(5, 5, 5, 4, 1, 0),
 			expected: false,
 		},
 		{
 			name: "not complete: min availability is not honored",
 
-			md:       deployment(5, 5, 5, 3, 1, 0),
+			d:        deployment(5, 5, 5, 3, 1, 0),
 			expected: false,
 		},
 		{
 			name: "complete",
 
-			md:       deployment(5, 5, 5, 5, 0, 0),
+			d:        deployment(5, 5, 5, 5, 0, 0),
 			expected: true,
 		},
 		{
 			name: "not complete: all machines are available but not updated",
 
-			md:       deployment(5, 5, 4, 5, 0, 0),
+			d:        deployment(5, 5, 4, 5, 0, 0),
 			expected: false,
 		},
 		{
@@ -650,13 +650,13 @@ func TestDeploymentComplete(t *testing.T) {
 
 			// old machine set: spec.replicas=1, status.replicas=1, status.availableReplicas=1
 			// new machine set: spec.replicas=1, status.replicas=1, status.availableReplicas=0
-			md:       deployment(1, 2, 1, 1, 0, 1),
+			d:        deployment(1, 2, 1, 1, 0, 1),
 			expected: false,
 		},
 		{
 			name: "not complete: one replica deployment never comes up",
 
-			md:       deployment(1, 1, 1, 0, 1, 1),
+			d:        deployment(1, 1, 1, 0, 1, 1),
 			expected: false,
 		},
 	}
@@ -665,7 +665,7 @@ func TestDeploymentComplete(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			g := NewWithT(t)
 
-			g.Expect(DeploymentComplete(test.md, &test.md.Status)).To(Equal(test.expected))
+			g.Expect(DeploymentComplete(test.d, &test.d.Status)).To(Equal(test.expected))
 		})
 	}
 }
diff --git a/internal/util/taints/taints_test.go b/internal/util/taints/taints_test.go
deleted file mode 100644
index f830c9573..000000000
--- a/internal/util/taints/taints_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright 2023 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 taints
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-	corev1 "k8s.io/api/core/v1"
-)
-
-func TestRemoveNodeTaint(t *testing.T) {
-	taint1 := corev1.Taint{Key: "taint1", Effect: corev1.TaintEffectNoSchedule}
-	taint2 := corev1.Taint{Key: "taint2", Effect: corev1.TaintEffectNoSchedule}
-
-	tests := []struct {
-		name         string
-		node         *corev1.Node
-		dropTaint    corev1.Taint
-		wantTaints   []corev1.Taint
-		wantModified bool
-	}{
-		{
-			name: "dropping taint from node should return true",
-			node: &corev1.Node{Spec: corev1.NodeSpec{
-				Taints: []corev1.Taint{
-					taint1,
-					taint2,
-				}}},
-			dropTaint:    taint1,
-			wantTaints:   []corev1.Taint{taint2},
-			wantModified: true,
-		},
-		{
-			name: "drop non-existing taint should return false",
-			node: &corev1.Node{Spec: corev1.NodeSpec{
-				Taints: []corev1.Taint{
-					taint2,
-				}}},
-			dropTaint:    taint1,
-			wantTaints:   []corev1.Taint{taint2},
-			wantModified: false,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			g := NewWithT(t)
-			got := RemoveNodeTaint(tt.node, tt.dropTaint)
-			g.Expect(got).To(Equal(tt.wantModified))
-			g.Expect(tt.node.Spec.Taints).To(Equal(tt.wantTaints))
-		})
-	}
-}
diff --git a/test/go.mod b/test/go.mod
index 4b3bd0cf5..94150499e 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -10,8 +10,8 @@ require (
 	github.com/docker/go-connections v0.4.0
 	github.com/flatcar/ignition v0.36.2
 	github.com/go-logr/logr v1.2.3
-	github.com/onsi/ginkgo/v2 v2.9.0
-	github.com/onsi/gomega v1.27.2
+	github.com/onsi/ginkgo/v2 v2.8.4
+	github.com/onsi/gomega v1.27.1
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/pflag v1.0.5
 	github.com/vincent-petithory/dataurl v1.0.0
@@ -110,11 +110,11 @@ require (
 	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
 	golang.org/x/crypto v0.3.0 // indirect
-	golang.org/x/net v0.8.0 // indirect
-	golang.org/x/oauth2 v0.6.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/term v0.6.0 // indirect
-	golang.org/x/text v0.8.0 // indirect
+	golang.org/x/net v0.7.0 // indirect
+	golang.org/x/oauth2 v0.5.0 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/term v0.5.0 // indirect
+	golang.org/x/text v0.7.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/tools v0.6.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
diff --git a/test/go.sum b/test/go.sum
index 33a52d466..24b56791e 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -385,10 +385,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
-github.com/onsi/ginkgo/v2 v2.9.0 h1:Tugw2BKlNHTMfG+CheOITkYvk4LAh6MFOvikhGVnhE8=
-github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk=
-github.com/onsi/gomega v1.27.2 h1:SKU0CXeKE/WVgIV1T61kSa3+IRE8Ekrv9rdXDwwTqnY=
-github.com/onsi/gomega v1.27.2/go.mod h1:5mR3phAHpkAVIDkHEUBY6HGVsU+cpcEscrGPB4oPlZI=
+github.com/onsi/ginkgo/v2 v2.8.4 h1:gf5mIQ8cLFieruNLAdgijHF1PYfLphKm2dxxcUtcqK0=
+github.com/onsi/ginkgo/v2 v2.8.4/go.mod h1:427dEDQZkDKsBvCjc2A/ZPefhKxsTTrsQegMlayL730=
+github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754=
+github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
@@ -634,8 +634,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -647,8 +647,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
-golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
+golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
+golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -717,13 +717,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -734,8 +734,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=