Repository: kubernetes-sigs/cluster-api
Pull request #7976 (2023-01-23 17:46:43)

:bug:  Use tenancy as filter in ownerReference test
This change cleans up the implementation introduced in #7973 using the tenancy concept exposed in the objectGraph returned by the call to discovery.



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 assign cecilerobertmichon for approval by writing `/assign @cecilerobertmichon` in a comment. 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:

- **[OWNERS](https://github.com/kubernetes-sigs/cluster-api/blob/main/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":["cecilerobertmichon"]} -->
sbueringer: /lgtm
/assign @fabriziopandini 

Nice catch @fabriziopandini 
k8s-ci-robot: LGTM label has been added.  <details>Git tree hash: 9a572afc5a2218ad71f1b2908186d7e0fe4b6943</details>
k8s-ci-robot: New changes are detected. LGTM label has been removed.
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 fabriziopandini by writing `/assign @fabriziopandini` in a comment. 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:

- **[OWNERS](https://github.com/kubernetes-sigs/cluster-api/blob/main/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":["fabriziopandini"]} -->
k8s-ci-robot: LGTM label has been added.  <details>Git tree hash: 1603c5ba2e92987d7e112e2433a967aeb1e24ff8</details>
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/cluster-api/pull/7976#pullrequestreview-1266131304" title="Approved">fabriziopandini</a>*

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

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

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

- ~~[OWNERS](https://github.com/kubernetes-sigs/cluster-api/blob/main/OWNERS)~~ [fabriziopandini]

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: /retest

I think we need to re-run the netlify tests.
vincepri: Kicked off a re-run from the GitHub UI 🤔 not sure if that did it though
vincepri: @killianmuldoon might have to rebase/force-push to re-trigger netlify
sbueringer: Yup had the same on a different PR. Maybe it's this issue: https://answers.netlify.com/t/clear-cache-and-retry-for-deploy-preview-does-not-update-pull-request/81755

Didn't have any success with retries otherwise.

Patch:
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index 45559a17d..8de946dfe 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -23,7 +23,7 @@ jobs:
         with:
           go-version: 1.19
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 # tag=v3.4.0
+        uses: golangci/golangci-lint-action@0ad9a0988b3973e851ab0a07adf248ec2e100376 # tag=v3.3.1
         with:
           version: v1.50.1
           working-directory: ${{matrix.working-directory}}
diff --git a/Tiltfile b/Tiltfile
index 58cad6c43..224000690 100644
--- a/Tiltfile
+++ b/Tiltfile
@@ -49,7 +49,7 @@ always_enable_providers = ["core"]
 
 providers = {
     "core": {
-        "context": ".",  # NOTE: this should be kept in sync with corresponding setting in tilt-prepare
+        "context": ".",
         "image": "gcr.io/k8s-staging-cluster-api/cluster-api-controller",
         "live_reload_deps": [
             "main.go",
@@ -68,7 +68,7 @@ providers = {
         "label": "CAPI",
     },
     "kubeadm-bootstrap": {
-        "context": "bootstrap/kubeadm",  # NOTE: this should be kept in sync with corresponding setting in tilt-prepare
+        "context": "bootstrap/kubeadm",
         "image": "gcr.io/k8s-staging-cluster-api/kubeadm-bootstrap-controller",
         "live_reload_deps": [
             "main.go",
@@ -82,7 +82,7 @@ providers = {
         "label": "CABPK",
     },
     "kubeadm-control-plane": {
-        "context": "controlplane/kubeadm",  # NOTE: this should be kept in sync with corresponding setting in tilt-prepare
+        "context": "controlplane/kubeadm",
         "image": "gcr.io/k8s-staging-cluster-api/kubeadm-control-plane-controller",
         "live_reload_deps": [
             "main.go",
@@ -95,7 +95,7 @@ providers = {
         "label": "KCP",
     },
     "docker": {
-        "context": "test/infrastructure/docker",  # NOTE: this should be kept in sync with corresponding setting in tilt-prepare
+        "context": "test/infrastructure/docker",
         "image": "gcr.io/k8s-staging-cluster-api/capd-manager",
         "live_reload_deps": [
             "main.go",
@@ -121,7 +121,7 @@ COPY --from=tilt-helper /usr/bin/kubectl /usr/bin/kubectl
 """,
     },
     "test-extension": {
-        "context": "test/extension",  # NOTE: this should be kept in sync with corresponding setting in tilt-prepare
+        "context": "test/extension",
         "image": "gcr.io/k8s-staging-cluster-api/test-extension",
         "live_reload_deps": [
             "main.go",
diff --git a/cmd/clusterctl/client/cluster/ownergraph.go b/cmd/clusterctl/client/cluster/ownergraph.go
index d65ad7def..fc12f9150 100644
--- a/cmd/clusterctl/client/cluster/ownergraph.go
+++ b/cmd/clusterctl/client/cluster/ownergraph.go
@@ -20,9 +20,6 @@ import (
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-
-	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
 )
 
 // OwnerGraph contains a graph with all the objects considered by clusterctl move as nodes and the OwnerReference relationship
@@ -61,12 +58,8 @@ func GetOwnerGraph(namespace, kubeconfigPath string) (OwnerGraph, error) {
 
 	graph := newObjectGraph(p, invClient)
 
-	cl, err := p.NewClient()
-	if err != nil {
-		return OwnerGraph{}, errors.Wrap(err, "failed to create client for ownerGraph")
-	}
 	// Gets all the types defined by the CRDs installed by clusterctl plus the ConfigMap/Secret core types.
-	err = graph.getDiscoveryTypes()
+	err := graph.getDiscoveryTypes()
 	if err != nil {
 		return OwnerGraph{}, errors.Wrap(err, "failed to retrieve discovery types")
 	}
@@ -78,18 +71,8 @@ func GetOwnerGraph(namespace, kubeconfigPath string) (OwnerGraph, error) {
 		return OwnerGraph{}, errors.Wrap(err, "failed to discover the object graph")
 	}
 	owners := OwnerGraph{}
-	for _, v := range graph.uidToNode {
-		// The Discovery function returns all secrets in the Cluster namespace. Ensure a Secret that is not part of the
-		// Cluster is not added to the OwnerGraph.
-		if v.identity.Kind == "Secret" {
-			clusterSecret, err := isClusterSecret(v.identity, cl)
-			if err != nil {
-				return OwnerGraph{}, err
-			}
-			if !clusterSecret {
-				continue
-			}
-		}
+	// Using getMoveNodes here ensures only objects that are part of the Cluster are added to the OwnerGraph.
+	for _, v := range graph.getMoveNodes() {
 		n := OwnerGraphNode{Object: v.identity, Owners: []metav1.OwnerReference{}}
 		for owner, attributes := range v.owners {
 			n.Owners = append(n.Owners, nodeToOwnerRef(owner, attributes))
@@ -98,12 +81,3 @@ func GetOwnerGraph(namespace, kubeconfigPath string) (OwnerGraph, error) {
 	}
 	return owners, nil
 }
-
-// isClusterSecret checks whether a Secret is related to a CAPI Cluster by checking if the secret type is ClusterSecretType.
-func isClusterSecret(ref corev1.ObjectReference, c client.Client) (bool, error) {
-	s := &corev1.Secret{}
-	if err := c.Get(ctx, client.ObjectKey{Namespace: ref.Namespace, Name: ref.Name}, s); err != nil {
-		return false, err
-	}
-	return s.Type == clusterv1.ClusterSecretType, nil
-}
diff --git a/cmd/clusterctl/cmd/util.go b/cmd/clusterctl/cmd/util.go
index 2ab45cbb6..59440a132 100644
--- a/cmd/clusterctl/cmd/util.go
+++ b/cmd/clusterctl/cmd/util.go
@@ -38,15 +38,15 @@ func printYamlOutput(printer client.YamlPrinter, outputFile string) error {
 	if err != nil {
 		return err
 	}
+	outputFile = filepath.Clean(strings.TrimSpace(outputFile))
 	yaml = append(yaml, '\n')
-	outputFile = strings.TrimSpace(outputFile)
 	if outputFile == "" || outputFile == "-" {
 		if _, err := os.Stdout.Write(yaml); err != nil {
 			return errors.Wrap(err, "failed to write yaml to Stdout")
 		}
 		return nil
 	}
-	outputFile = filepath.Clean(outputFile)
+
 	if err := os.WriteFile(outputFile, yaml, 0600); err != nil {
 		return errors.Wrap(err, "failed to write to destination file")
 	}
diff --git a/docs/book/src/developer/tilt.md b/docs/book/src/developer/tilt.md
index 42f7200a0..987f7561c 100644
--- a/docs/book/src/developer/tilt.md
+++ b/docs/book/src/developer/tilt.md
@@ -394,9 +394,6 @@ build it.
 **live_reload_deps**: a list of files/directories to watch. If any of them changes, Tilt rebuilds the manager binary
 for the provider and performs a live update of the running container.
 
-**version**: allows to define the version to be used for the Provider CR. If empty, a default version will 
-be used.
-
 **additional_docker_helper_commands** (String, default=""): Additional commands to be run in the helper image
 docker build. e.g.
 
@@ -481,4 +478,4 @@ syntax highlighting and auto-formatting. To enable it for Tiltfile a file associ
 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.
+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.
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 6aeb55c98..b58e48701 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/docker/distribution v2.8.1+incompatible
 	github.com/drone/envsubst/v2 v2.0.0-20210730161058-179042472c46
 	github.com/evanphx/json-patch/v5 v5.6.0
-	github.com/fatih/color v1.14.1
+	github.com/fatih/color v1.13.0
 	github.com/flatcar/container-linux-config-transpiler v0.9.4
 	github.com/flatcar/ignition v0.36.2
 	github.com/go-logr/logr v1.2.3
@@ -88,7 +88,7 @@ require (
 	github.com/magiconair/properties v1.8.6 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-isatty v0.0.17 // indirect
+	github.com/mattn/go-isatty v0.0.16 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect
diff --git a/go.sum b/go.sum
index 28ab13c8d..3b903ad3c 100644
--- a/go.sum
+++ b/go.sum
@@ -150,8 +150,8 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
 github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
 github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
-github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
+github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
 github.com/flatcar/container-linux-config-transpiler v0.9.4 h1:yXQ0NB8PeNrKJPrZvbv5/DV63PNhTqt8vaf8YxmX/RA=
 github.com/flatcar/container-linux-config-transpiler v0.9.4/go.mod h1:LxanhPvXkWgHG9PrkT4rX/p7YhUPdDGGsUdkNpV3L5U=
 github.com/flatcar/ignition v0.36.2 h1:xGHgScUe0P4Fkprjqv7L2CE58emiQgP833OCCn9z2v4=
@@ -360,12 +360,14 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
-github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
 github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -728,6 +730,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -758,6 +761,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/hack/tools/tilt-prepare/main.go b/hack/tools/tilt-prepare/main.go
index 6e4855c82..c26943ebb 100644
--- a/hack/tools/tilt-prepare/main.go
+++ b/hack/tools/tilt-prepare/main.go
@@ -64,73 +64,45 @@ Example call for tilt up:
 	--tools kustomize,envsubst
 */
 
-const (
-	kustomizePath = "./hack/tools/bin/kustomize"
-	envsubstPath  = "./hack/tools/bin/envsubst"
-)
-
 var (
-	// Defines the default version to be used for the provider CR if no version is specified in the tilt-provider.yaml|json file.
-	defaultProviderVersion = "v1.4.99"
-
-	// This data struct mirrors a subset of info from the providers struct in the tilt file
-	// which is containing "hard-coded" tilt-provider.yaml files for the providers managed in the Cluster API repository.
-	providers = map[string]tiltProviderConfig{
-		"core": {
-			Context: pointer.String("."),
-		},
-		"kubeadm-bootstrap": {
-			Context: pointer.String("bootstrap/kubeadm"),
-		},
-		"kubeadm-control-plane": {
-			Context: pointer.String("controlplane/kubeadm"),
-		},
-		"docker": {
-			Context: pointer.String("test/infrastructure/docker"),
-		},
-		"test-extension": {
-			Context: pointer.String("test/extension"),
-		},
-	}
-
 	rootPath             string
 	tiltBuildPath        string
 	tiltSettingsFileFlag = pflag.String("tilt-settings-file", "./tilt-settings.yaml", "Path to a tilt-settings.(json|yaml) file")
 	toolsFlag            = pflag.StringSlice("tools", []string{}, "list of tools to be created; each value should correspond to a make target")
 )
 
-// Types used to de-serialize the tilt-settings.yaml/json file from the Cluster API repository.
-
 type tiltSettings struct {
-	Debug               map[string]tiltSettingsDebugConfig `json:"debug,omitempty"`
-	ExtraArgs           map[string]tiltSettingsExtraArgs   `json:"extra_args,omitempty"`
-	DeployCertManager   *bool                              `json:"deploy_cert_manager,omitempty"`
-	DeployObservability []string                           `json:"deploy_observability,omitempty"`
-	EnableProviders     []string                           `json:"enable_providers,omitempty"`
-	AllowedContexts     []string                           `json:"allowed_contexts,omitempty"`
-	ProviderRepos       []string                           `json:"provider_repos,omitempty"`
+	Debug               map[string]debugConfig `json:"debug,omitempty"`
+	ExtraArgs           map[string]extraArgs   `json:"extra_args,omitempty"`
+	DeployCertManager   *bool                  `json:"deploy_cert_manager,omitempty"`
+	DeployObservability []string               `json:"deploy_observability,omitempty"`
+	EnableProviders     []string               `json:"enable_providers,omitempty"`
+	AllowedContexts     []string               `json:"allowed_contexts,omitempty"`
+	ProviderRepos       []string               `json:"provider_repos,omitempty"`
+}
+
+type providerSettings struct {
+	Name   string          `json:"name,omitempty"`
+	Config *providerConfig `json:"config,omitempty"`
 }
 
-type tiltSettingsDebugConfig struct {
+type providerConfig struct {
+	Context *string `json:"context,omitempty"`
+}
+
+type debugConfig struct {
 	Continue     *bool `json:"continue"`
 	Port         *int  `json:"port"`
 	ProfilerPort *int  `json:"profiler_port"`
 	MetricsPort  *int  `json:"metrics_port"`
 }
 
-type tiltSettingsExtraArgs []string
-
-// Types used to de-serialize the tilt-providers.yaml/json file from the provider repositories.
+type extraArgs []string
 
-type tiltProvider struct {
-	Name   string              `json:"name,omitempty"`
-	Config *tiltProviderConfig `json:"config,omitempty"`
-}
-
-type tiltProviderConfig struct {
-	Context *string `json:"context,omitempty"`
-	Version *string `json:"version,omitempty"`
-}
+const (
+	kustomizePath = "./hack/tools/bin/kustomize"
+	envsubstPath  = "./hack/tools/bin/envsubst"
+)
 
 func init() {
 	cmd := exec.Command("git", "rev-parse", "--show-toplevel")
@@ -197,12 +169,12 @@ func readTiltSettings(path string) (*tiltSettings, error) {
 		return nil, errors.Wrap(err, "failed to unmarshal tilt-settings content")
 	}
 
-	setTiltSettingsDefaults(ts)
+	setDefaults(ts)
 	return ts, nil
 }
 
-// setTiltSettingsDefaults sets default values for tiltSettings info.
-func setTiltSettingsDefaults(ts *tiltSettings) {
+// setDefaults sets default values for debug related fields in tiltSettings.
+func setDefaults(ts *tiltSettings) {
 	if ts.DeployCertManager == nil {
 		ts.DeployCertManager = pointer.Bool(true)
 	}
@@ -291,15 +263,22 @@ func tiltResources(ctx context.Context, ts *tiltSettings) error {
 		)
 	}
 
-	// Add read configurations from provider repos
+	providerPaths := map[string]string{"core": ".",
+		"kubeadm-bootstrap":     "bootstrap/kubeadm",
+		"kubeadm-control-plane": "controlplane/kubeadm",
+		"docker":                "test/infrastructure/docker",
+		"test-extension":        "test/extension",
+	}
+
+	// Add all the provider paths to the providerpaths map
 	for _, p := range ts.ProviderRepos {
-		tiltProviderConfigs, err := loadTiltProvider(p)
+		providerContexts, err := loadProviders(p)
 		if err != nil {
-			return errors.Wrapf(err, "failed to load tilt-provider.yaml/json from %s", p)
+			return err
 		}
 
-		for name, config := range tiltProviderConfigs {
-			providers[name] = config
+		for name, path := range providerContexts {
+			providerPaths[name] = path
 		}
 	}
 
@@ -315,41 +294,37 @@ func tiltResources(ctx context.Context, ts *tiltSettings) error {
 
 	// Add the provider task for each of the enabled provider
 	for _, providerName := range ts.EnableProviders {
-		config, ok := providers[providerName]
+		path, ok := providerPaths[providerName]
 		if !ok {
-			return errors.Errorf("failed to obtain config for the provider %s, please add the providers path to the provider_repos list in tilt-settings.yaml/json file", providerName)
+			return errors.Errorf("failed to obtain path for the provider %s", providerName)
 		}
-		tasks[providerName] = workloadTask(providerName, "provider", "manager", "manager", ts, fmt.Sprintf("%s/config/default", *config.Context), getProviderObj(config.Version))
+		tasks[providerName] = workloadTask(providerName, "provider", "manager", "manager", ts, fmt.Sprintf("%s/config/default", path), getProviderObj)
 	}
 
 	return runTaskGroup(ctx, "resources", tasks)
 }
 
-func loadTiltProvider(providerRepository string) (map[string]tiltProviderConfig, error) {
-	tiltProviders, err := readTiltProvider(providerRepository)
+func loadProviders(r string) (map[string]string, error) {
+	var contextPath string
+	providerData, err := readProviderSettings(r)
 	if err != nil {
 		return nil, err
 	}
 
-	ret := make(map[string]tiltProviderConfig)
-	for _, p := range tiltProviders {
-		if p.Config == nil {
-			return nil, errors.Errorf("tilt-provider.yaml/json file from %s does not contain a config section for provider %s", providerRepository, p.Name)
-		}
-
-		// Resolving context, that is a relative path to the repository where the tilt-provider is defined
-		contextPath := filepath.Join(providerRepository, pointer.StringDeref(p.Config.Context, "."))
-
-		ret[p.Name] = tiltProviderConfig{
-			Context: &contextPath,
-			Version: p.Config.Version,
+	providerContexts := map[string]string{}
+	for _, p := range providerData {
+		if p.Config != nil && p.Config.Context != nil {
+			contextPath = r + "/" + *p.Config.Context
+		} else {
+			contextPath = r
 		}
+		providerContexts[p.Name] = contextPath
 	}
-	return ret, nil
+	return providerContexts, nil
 }
 
-func readTiltProvider(path string) ([]tiltProvider, error) {
-	path, err := addTiltProviderFile(path)
+func readProviderSettings(path string) ([]providerSettings, error) {
+	path, err := checkWorkloadFileFormat(path, "provider")
 	if err != nil {
 		return nil, err
 	}
@@ -359,14 +334,14 @@ func readTiltProvider(path string) ([]tiltProvider, error) {
 		return nil, err
 	}
 
-	ps := []tiltProvider{}
+	ps := []providerSettings{}
 	// providerSettings file can be an array and this is done to detect arrays
 	if strings.HasPrefix(string(content), "[") || strings.HasPrefix(string(content), "-") {
 		if err := yaml.Unmarshal(content, &ps); err != nil {
 			return nil, errors.Wrap(err, fmt.Sprintf("failed to read provider path %s tilt file", path))
 		}
 	} else {
-		p := tiltProvider{}
+		p := providerSettings{}
 		if err := yaml.Unmarshal(content, &p); err != nil {
 			return nil, errors.Wrap(err, fmt.Sprintf("failed to read provider path %s tilt file", path))
 		}
@@ -375,16 +350,14 @@ func readTiltProvider(path string) ([]tiltProvider, error) {
 	return ps, nil
 }
 
-func addTiltProviderFile(path string) (string, error) {
-	pathAndFile := filepath.Join(path, "tilt-provider.yaml")
-	if _, err := os.Stat(pathAndFile); err == nil {
-		return pathAndFile, nil
+func checkWorkloadFileFormat(path, workloadType string) (string, error) {
+	if _, err := os.Stat(path + fmt.Sprintf("/tilt-%s.yaml", workloadType)); err == nil {
+		return path + fmt.Sprintf("/tilt-%s.yaml", workloadType), nil
 	}
-	pathAndFile = filepath.Join(path, "tilt-provider.json")
-	if _, err := os.Stat(pathAndFile); err == nil {
-		return pathAndFile, nil
+	if _, err := os.Stat(path + fmt.Sprintf("/tilt-%s.json", workloadType)); err == nil {
+		return path + fmt.Sprintf("/tilt-%s.json", workloadType), nil
 	}
-	return "", errors.Errorf("unable to find a tilt-provider.yaml|json file under %s", path)
+	return "", fmt.Errorf("unable to find a tilt %s file under %s", workloadType, path)
 }
 
 type taskFunction func(ctx context.Context, prefix string, errors chan error)
@@ -894,72 +867,70 @@ func updateDeployment(prefix string, objs []unstructured.Unstructured, f updateD
 	return nil
 }
 
-func getProviderObj(version *string) func(prefix string, objs []unstructured.Unstructured) (*unstructured.Unstructured, error) {
-	return func(prefix string, objs []unstructured.Unstructured) (*unstructured.Unstructured, error) {
-		namespace := ""
-		manifestLabel := ""
-		for i := range objs {
-			if objs[i].GetKind() != "Namespace" {
-				continue
-			}
-
-			namespace = objs[i].GetName()
-			manifestLabel = objs[i].GetLabels()[clusterv1.ProviderNameLabel]
-			break
+func getProviderObj(prefix string, objs []unstructured.Unstructured) (*unstructured.Unstructured, error) {
+	namespace := ""
+	manifestLabel := ""
+	for i := range objs {
+		if objs[i].GetKind() != "Namespace" {
+			continue
 		}
 
-		if manifestLabel == "" {
-			return nil, errors.Errorf(
-				"Could not find any Namespace object with label %s and therefore failed to deduce provider name and type",
-				clusterv1.ProviderNameLabel)
-		}
+		namespace = objs[i].GetName()
+		manifestLabel = objs[i].GetLabels()[clusterv1.ProviderNameLabel]
+		break
+	}
 
-		providerType := string(clusterctlv1.CoreProviderType)
-		providerName := manifestLabel
-		if strings.HasPrefix(manifestLabel, "infrastructure-") {
-			providerType = string(clusterctlv1.InfrastructureProviderType)
-			providerName = manifestLabel[len("infrastructure-"):]
-		}
-		if strings.HasPrefix(manifestLabel, "bootstrap-") {
-			providerType = string(clusterctlv1.BootstrapProviderType)
-			providerName = manifestLabel[len("bootstrap-"):]
-		}
-		if strings.HasPrefix(manifestLabel, "control-plane-") {
-			providerType = string(clusterctlv1.ControlPlaneProviderType)
-			providerName = manifestLabel[len("control-plane-"):]
-		}
-		if strings.HasPrefix(manifestLabel, "ipam-") {
-			providerType = string(clusterctlv1.IPAMProviderType)
-			providerName = manifestLabel[len("ipam-"):]
-		}
-		if strings.HasPrefix(manifestLabel, "runtime-extension-") {
-			providerType = string(clusterctlv1.RuntimeExtensionProviderType)
-			providerName = manifestLabel[len("runtime-extension-"):]
-		}
+	if manifestLabel == "" {
+		return nil, errors.Errorf(
+			"Could not find any Namespace object with label %s and therefore failed to deduce provider name and type",
+			clusterv1.ProviderNameLabel)
+	}
 
-		provider := &clusterctlv1.Provider{
-			TypeMeta: metav1.TypeMeta{
-				Kind:       "Provider",
-				APIVersion: clusterctlv1.GroupVersion.String(),
-			},
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      manifestLabel,
-				Namespace: namespace,
-				Labels: map[string]string{
-					clusterv1.ProviderNameLabel:      manifestLabel,
-					clusterctlv1.ClusterctlLabel:     "",
-					clusterctlv1.ClusterctlCoreLabel: clusterctlv1.ClusterctlCoreLabelInventoryValue,
-				},
+	providerType := string(clusterctlv1.CoreProviderType)
+	providerName := manifestLabel
+	if strings.HasPrefix(manifestLabel, "infrastructure-") {
+		providerType = string(clusterctlv1.InfrastructureProviderType)
+		providerName = manifestLabel[len("infrastructure-"):]
+	}
+	if strings.HasPrefix(manifestLabel, "bootstrap-") {
+		providerType = string(clusterctlv1.BootstrapProviderType)
+		providerName = manifestLabel[len("bootstrap-"):]
+	}
+	if strings.HasPrefix(manifestLabel, "control-plane-") {
+		providerType = string(clusterctlv1.ControlPlaneProviderType)
+		providerName = manifestLabel[len("control-plane-"):]
+	}
+	if strings.HasPrefix(manifestLabel, "ipam-") {
+		providerType = string(clusterctlv1.IPAMProviderType)
+		providerName = manifestLabel[len("ipam-"):]
+	}
+	if strings.HasPrefix(manifestLabel, "runtime-extension-") {
+		providerType = string(clusterctlv1.RuntimeExtensionProviderType)
+		providerName = manifestLabel[len("runtime-extension-"):]
+	}
+
+	provider := &clusterctlv1.Provider{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "Provider",
+			APIVersion: clusterctlv1.GroupVersion.String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      manifestLabel,
+			Namespace: namespace,
+			Labels: map[string]string{
+				clusterv1.ProviderNameLabel:      manifestLabel,
+				clusterctlv1.ClusterctlLabel:     "",
+				clusterctlv1.ClusterctlCoreLabel: clusterctlv1.ClusterctlCoreLabelInventoryValue,
 			},
-			ProviderName: providerName,
-			Type:         providerType,
-			Version:      pointer.StringDeref(version, defaultProviderVersion),
-		}
+		},
+		ProviderName: providerName,
+		Type:         providerType,
+		Version:      "v1.4.99",
+	}
 
-		providerObj := &unstructured.Unstructured{}
-		if err := scheme.Scheme.Convert(provider, providerObj, nil); err != nil {
-			return nil, errors.Wrapf(err, "[%s] failed to convert Provider to unstructured", prefix)
-		}
-		return providerObj, nil
+	providerObj := &unstructured.Unstructured{}
+	if err := scheme.Scheme.Convert(provider, providerObj, nil); err != nil {
+		return nil, errors.Wrapf(err, "[%s] failed to convert Provider to unstructured", prefix)
 	}
+	return providerObj, nil
 }
diff --git a/hack/verify-starlark.sh b/hack/verify-starlark.sh
index 0d65a734c..bc6d7c028 100755
--- a/hack/verify-starlark.sh
+++ b/hack/verify-starlark.sh
@@ -73,3 +73,4 @@ fi
 echo "Running buildifier..."
 cd "${ROOT_PATH}" || exit
 "${BUILDIFIER}" -mode=${MODE} Tiltfile >> "${OUT}" 2>&1
+
diff --git a/internal/controllers/machine/machine_controller.go b/internal/controllers/machine/machine_controller.go
index d10020fa0..2ba71f8b7 100644
--- a/internal/controllers/machine/machine_controller.go
+++ b/internal/controllers/machine/machine_controller.go
@@ -91,11 +91,7 @@ type Reconciler struct {
 	// nodeDeletionRetryTimeout determines how long the controller will retry deleting a node
 	// during a single reconciliation.
 	nodeDeletionRetryTimeout time.Duration
-
-	// disableNodeLabelSync should only be used for tests. This is used to skip the parts of
-	// the controller that need SSA as the current test setup does not support SSA.
-	// This flag should be dropped after the tests are migrated to envtest.
-	disableNodeLabelSync bool
+	disableNodeLabelSync     bool
 }
 
 func (r *Reconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {


Test patch:
diff --git a/test/e2e/quick_start.go b/test/e2e/quick_start.go
index 983efdf77..5aa42250c 100644
--- a/test/e2e/quick_start.go
+++ b/test/e2e/quick_start.go
@@ -39,31 +39,12 @@ type QuickStartSpecInput struct {
 	BootstrapClusterProxy framework.ClusterProxy
 	ArtifactFolder        string
 	SkipCleanup           bool
-
-	// InfrastructureProvider allows to specify the infrastructure provider to be used when looking for
-	// cluster templates.
-	// If not set, clusterctl will look at the infrastructure provider installed in the management cluster;
-	// if only one infrastructure provider exists, it will be used, otherwise the operation will fail if more than one exists.
-	InfrastructureProvider *string
+	ControlPlaneWaiters   clusterctl.ControlPlaneWaiters
 
 	// Flavor, if specified is the template flavor used to create the cluster for testing.
-	// If not specified, the default flavor for the selected infrastructure provider is used.
-	Flavor *string
-
-	// ControlPlaneMachineCount defines the number of control plane machines to be added to the workload cluster.
-	// If not specified, 1 will be used.
-	ControlPlaneMachineCount *int64
-
-	// WorkerMachineCount defines number of worker machines to be added to the workload cluster.
-	// If not specified, 1 will be used.
-	WorkerMachineCount *int64
-
-	// Allows to inject functions to be run while waiting for the control plane to be initialized,
-	// which unblocks CNI installation, and for the control plane machines to be ready (after CNI installation).
-	ControlPlaneWaiters clusterctl.ControlPlaneWaiters
-
-	// Allows to inject a function to be run after machines are provisioned.
-	// If not specified, this is a no-op.
+	// If not specified, and the e2econfig variable IPFamily is IPV6, then "ipv6" is used,
+	// otherwise the default flavor is used.
+	Flavor                  *string
 	PostMachinesProvisioned func(managementClusterProxy framework.ClusterProxy, workloadClusterNamespace, workloadClusterName string)
 }
 
@@ -98,26 +79,10 @@ func QuickStartSpec(ctx context.Context, inputGetter func() QuickStartSpecInput)
 	It("Should create a workload cluster", func() {
 		By("Creating a workload cluster")
 
-		infrastructureProvider := clusterctl.DefaultInfrastructureProvider
-		if input.InfrastructureProvider != nil {
-			infrastructureProvider = *input.InfrastructureProvider
-		}
-
 		flavor := clusterctl.DefaultFlavor
 		if input.Flavor != nil {
 			flavor = *input.Flavor
 		}
-
-		controlPlaneMachineCount := pointer.Int64(1)
-		if input.ControlPlaneMachineCount != nil {
-			controlPlaneMachineCount = input.ControlPlaneMachineCount
-		}
-
-		workerMachineCount := pointer.Int64(1)
-		if input.WorkerMachineCount != nil {
-			workerMachineCount = input.WorkerMachineCount
-		}
-
 		clusterName := fmt.Sprintf("%s-%s", specName, util.RandomString(6))
 		clusterctl.ApplyClusterTemplateAndWait(ctx, clusterctl.ApplyClusterTemplateAndWaitInput{
 			ClusterProxy: input.BootstrapClusterProxy,
@@ -125,13 +90,13 @@ func QuickStartSpec(ctx context.Context, inputGetter func() QuickStartSpecInput)
 				LogFolder:                filepath.Join(input.ArtifactFolder, "clusters", input.BootstrapClusterProxy.GetName()),
 				ClusterctlConfigPath:     input.ClusterctlConfigPath,
 				KubeconfigPath:           input.BootstrapClusterProxy.GetKubeconfigPath(),
-				InfrastructureProvider:   infrastructureProvider,
+				InfrastructureProvider:   clusterctl.DefaultInfrastructureProvider,
 				Flavor:                   flavor,
 				Namespace:                namespace.Name,
 				ClusterName:              clusterName,
 				KubernetesVersion:        input.E2EConfig.GetVariable(KubernetesVersion),
-				ControlPlaneMachineCount: controlPlaneMachineCount,
-				WorkerMachineCount:       workerMachineCount,
+				ControlPlaneMachineCount: pointer.Int64(1),
+				WorkerMachineCount:       pointer.Int64(1),
 			},
 			ControlPlaneWaiters:          input.ControlPlaneWaiters,
 			WaitForClusterIntervals:      input.E2EConfig.GetIntervals(specName, "wait-cluster"),
diff --git a/test/framework/ownerreference_helpers.go b/test/framework/ownerreference_helpers.go
index 71b75951f..a1c0cc1fd 100644
--- a/test/framework/ownerreference_helpers.go
+++ b/test/framework/ownerreference_helpers.go
@@ -177,7 +177,7 @@ var KubernetesReferenceAssertions = map[string]func([]metav1.OwnerReference) err
 	},
 	configMapKind: func(owners []metav1.OwnerReference) error {
 		// The only configMaps considered here are those owned by a ClusterResourceSet.
-		return hasOneOfExactOwnersByGVK(owners, []schema.GroupVersionKind{clusterResourceSetGVK}, []schema.GroupVersionKind{})
+		return hasOneOfExactOwnersByGVK(owners, []schema.GroupVersionKind{clusterResourceSetGVK})
 	},
 }
 
diff --git a/test/go.mod b/test/go.mod
index 3dc286fdd..6b48a418b 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -77,7 +77,7 @@ require (
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/magiconair/properties v1.8.6 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
-	github.com/mattn/go-isatty v0.0.17 // indirect
+	github.com/mattn/go-isatty v0.0.16 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
diff --git a/test/go.sum b/test/go.sum
index 58c2629ac..034e8b5dc 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -343,8 +343,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
-github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
 github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=